home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / app / paint_funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-08  |  129.3 KB  |  5,944 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. #include <glib.h>
  26.  
  27. #include "apptypes.h"
  28.  
  29. #include "appenv.h"
  30. #include "gimprc.h"
  31. #include "paint_funcs.h"
  32. #include "boundary.h"
  33. #include "tile_manager.h"
  34.  
  35. #include "tile_manager_pvt.h"  /* For copy-on-write */
  36. #include "tile_pvt.h"  /* For accessing the tiles directly */
  37. #include "tile.h"            /* ick. */
  38.  
  39. #include "libgimp/gimpintl.h"
  40. #include "libgimp/gimpmath.h"
  41. #include "libgimp/gimpcolorspace.h"
  42.  
  43. #define STD_BUF_SIZE       1021
  44. #define MAXDIFF            195076
  45. #define HASH_TABLE_SIZE    1021
  46. #define RANDOM_TABLE_SIZE  4096
  47. #define RANDOM_SEED        314159265
  48. #define EPSILON            0.0001
  49.  
  50. #define INT_MULT(a,b,t)  ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8))
  51.  
  52. /* This version of INT_MULT3 is very fast, but suffers from some
  53.    slight roundoff errors.  It returns the correct result 99.987
  54.    percent of the time */
  55. #define INT_MULT3(a,b,c,t)  ((t) = (a) * (b) * (c)+ 0x7F5B, \
  56.                             ((((t) >> 7) + (t)) >> 16))
  57. /*
  58.   This version of INT_MULT3 always gives the correct result, but runs at
  59.   approximatly one third the speed. */
  60. /*  #define INT_MULT3(a,b,c,t) (((a) * (b) * (c)+ 32512) / 65025.0)
  61.  */
  62.  
  63. #define INT_BLEND(a,b,alpha,tmp)  (INT_MULT((a)-(b), alpha, tmp) + (b))
  64.  
  65. typedef enum
  66. {
  67.   MinifyX_MinifyY,
  68.   MinifyX_MagnifyY,
  69.   MagnifyX_MinifyY,
  70.   MagnifyX_MagnifyY
  71. } ScaleType;
  72.  
  73. /*  Layer modes information  */
  74. typedef struct _LayerMode LayerMode;
  75. struct _LayerMode
  76. {
  77.   int affect_alpha;     /*  does the layer mode affect the alpha channel  */
  78.   int increase_opacity; /*  layer mode can increase opacity */
  79.   int decrease_opacity; /*  layer mode can decrease opacity */
  80.   char *name;           /*  layer mode specification  */
  81. };
  82.  
  83. LayerMode layer_modes[] =    /* This must obviously be in the same
  84.                  * order as the corresponding values
  85.                  * in the LayerModeEffects enumeration.
  86.                  */
  87. {
  88.   { 1, 1, 0, N_("Normal") },
  89.   { 1, 1, 0, N_("Dissolve") },
  90.   { 1, 1, 0, N_("Behind") },
  91.   { 0, 0, 0, N_("Multiply (Burn)") },
  92.   { 0, 0, 0, N_("Screen") },
  93.   { 0, 0, 0, N_("Overlay") },
  94.   { 0, 0, 0, N_("Difference") },
  95.   { 0, 0, 0, N_("Addition") },
  96.   { 0, 0, 0, N_("Subtraction") },
  97.   { 0, 0, 0, N_("Darken Only") },
  98.   { 0, 0, 0, N_("Lighten Only") },
  99.   { 0, 0, 0, N_("Hue") },
  100.   { 0, 0, 0, N_("Saturation") },
  101.   { 0, 0, 0, N_("Color") },
  102.   { 0, 0, 0, N_("Value") },
  103.   { 0, 0, 0, N_("Divide (Dodge)") },
  104.   { 1, 0, 1, N_("Erase") },
  105.   { 1, 1, 1, N_("Replace") },
  106.   { 1, 0, 1, N_("Anti Erase") }
  107. };
  108.  
  109. /*  ColorHash structure  */
  110. typedef struct _ColorHash ColorHash;
  111.  
  112. struct _ColorHash
  113. {
  114.   int pixel;           /*  R << 16 | G << 8 | B  */
  115.   int index;           /*  colormap index        */
  116.   const GimpImage* gimage;     
  117. };
  118.  
  119. static ColorHash color_hash_table [HASH_TABLE_SIZE];
  120. static int random_table [RANDOM_TABLE_SIZE];
  121. static int color_hash_misses;
  122. static int color_hash_hits;
  123. static unsigned char * tmp_buffer;  /* temporary buffer available upon request */
  124. static int tmp_buffer_size;
  125. static unsigned char no_mask = OPAQUE_OPACITY;
  126. static guchar add_lut[511];
  127.  
  128. /*******************************/
  129. /*  Local function prototypes  */
  130. static int *  make_curve         (double, int *);
  131. static void   run_length_encode  (unsigned char *, int *, int, int);
  132. static double cubic              (double, int, int, int, int);
  133. static void   apply_layer_mode_replace (unsigned char *, unsigned char *,
  134.                     unsigned char *, unsigned char *,
  135.                     int, int, int,
  136.                     int, int, int, int *);
  137. static void   rotate_pointers    (void **p, guint32 n);
  138.  
  139.  
  140. void
  141. update_tile_rowhints (Tile *tile, 
  142.               int   ymin, 
  143.               int   ymax)
  144. {
  145.   int bpp, ewidth;
  146.   int x,y;
  147.   guchar* ptr;
  148.   guchar alpha;
  149.   TileRowHint thishint;
  150.  
  151. #ifdef HINTS_SANITY
  152.   g_assert(tile!=NULL);
  153. #endif
  154.  
  155.   tile_sanitize_rowhints (tile);
  156.  
  157.   bpp = tile_bpp (tile);
  158.   ewidth = tile->ewidth;
  159.  
  160.   if (bpp == 1 || bpp == 3)
  161.     {
  162.       for (y=ymin; y<=ymax; y++)
  163.     tile_set_rowhint (tile, y, TILEROWHINT_OPAQUE);
  164.  
  165.       return;
  166.     }
  167.  
  168.   if (bpp == 4)
  169.     {
  170. #ifdef HINTS_SANITY
  171.       g_assert(tile!=NULL);
  172. #endif
  173.  
  174.       ptr = tile_data_pointer (tile, 0, ymin);
  175.  
  176. #ifdef HINTS_SANITY
  177.       g_assert(ptr!=NULL);
  178. #endif
  179.  
  180.       for (y = ymin; y <= ymax; y++)
  181.     {
  182.       thishint = tile_get_rowhint (tile, y);
  183.  
  184. #ifdef HINTS_SANITY
  185.       if (thishint==TILEROWHINT_BROKEN)
  186.         g_error("BROKEN y=%d",y);
  187.       if (thishint==TILEROWHINT_OUTOFRANGE)
  188.         g_error("OOR y=%d",y);
  189.       if (thishint==TILEROWHINT_UNDEFINED)
  190.         g_error("UNDEFINED y=%d - bpp=%d ew=%d eh=%d",
  191.             y,bpp,ewidth,eheight);
  192. #endif
  193.  
  194. #ifdef HINTS_SANITY
  195.       if (thishint == TILEROWHINT_TRANSPARENT ||
  196.           thishint == TILEROWHINT_MIXED ||
  197.           thishint == TILEROWHINT_OPAQUE)
  198.         {
  199.           goto next_row4;
  200.         }
  201.  
  202.       if (thishint != TILEROWHINT_UNKNOWN)
  203.         {
  204.           g_error("MEGABOGUS y=%d - bpp=%d ew=%d eh=%d",
  205.               y,bpp,ewidth,eheight);
  206.         }
  207. #endif
  208.  
  209.       if (thishint == TILEROWHINT_UNKNOWN)
  210.         {
  211.           alpha = ptr[3];
  212.  
  213.           /* row is all-opaque or all-transparent? */
  214.           if (alpha == 0 || alpha == 255)
  215.         {
  216.           if (ewidth > 1)
  217.             {
  218.               for (x = 1; x < ewidth; x++)
  219.             {
  220.               if (ptr[x*4 + 3] != alpha)
  221.                 {
  222.                   tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  223.                   goto next_row4;
  224.                 }
  225.             }
  226.             }
  227.           tile_set_rowhint (tile, y,
  228.                     (alpha == 0) ?
  229.                     TILEROWHINT_TRANSPARENT :
  230.                     TILEROWHINT_OPAQUE);
  231.         }
  232.           else
  233.         {
  234.           tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  235.         }
  236.         }
  237.  
  238.     next_row4:
  239.       ptr += 4 * ewidth;
  240.     }
  241.       
  242.       return;
  243.     }
  244.  
  245.   if (bpp == 2)
  246.     {
  247. #ifdef HINTS_SANITY
  248.       g_assert(tile!=NULL);
  249. #endif
  250.  
  251.       ptr = tile_data_pointer (tile, 0, ymin);
  252.  
  253. #ifdef HINTS_SANITY
  254.       g_assert(ptr!=NULL);
  255. #endif
  256.  
  257.       for (y = ymin; y <= ymax; y++)
  258.     {
  259.       thishint = tile_get_rowhint (tile, y);
  260.  
  261. #ifdef HINTS_SANITY
  262.       if (thishint==TILEROWHINT_BROKEN)
  263.         g_error("BROKEN y=%d",y);
  264.       if (thishint==TILEROWHINT_OUTOFRANGE)
  265.         g_error("OOR y=%d",y);
  266.       if (thishint==TILEROWHINT_UNDEFINED)
  267.         g_error("UNDEFINED y=%d - bpp=%d ew=%d eh=%d",
  268.             y,bpp,ewidth,eheight);
  269. #endif
  270.  
  271. #ifdef HINTS_SANITY
  272.       if (thishint == TILEROWHINT_TRANSPARENT ||
  273.           thishint == TILEROWHINT_MIXED ||
  274.           thishint == TILEROWHINT_OPAQUE)
  275.         {
  276.           goto next_row2;
  277.         }
  278.  
  279.       if (thishint != TILEROWHINT_UNKNOWN)
  280.         {
  281.           g_error("MEGABOGUS y=%d - bpp=%d ew=%d eh=%d",
  282.               y,bpp,ewidth,eheight);
  283.         }
  284. #endif
  285.  
  286.       if (thishint == TILEROWHINT_UNKNOWN)
  287.         {
  288.           alpha = ptr[1];
  289.  
  290.           /* row is all-opaque or all-transparent? */
  291.           if (alpha == 0 || alpha == 255)
  292.         {
  293.           if (ewidth > 1)
  294.             {
  295.               for (x = 1; x < ewidth; x++)
  296.             {
  297.               if (ptr[x*2 + 1] != alpha)
  298.                 {
  299.                   tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  300.                   goto next_row2;
  301.                 }
  302.             }
  303.             }
  304.           tile_set_rowhint (tile, y,
  305.                     (alpha == 0) ?
  306.                     TILEROWHINT_TRANSPARENT :
  307.                     TILEROWHINT_OPAQUE);
  308.         }
  309.           else
  310.         {
  311.           tile_set_rowhint (tile, y, TILEROWHINT_MIXED);
  312.         }
  313.         }
  314.  
  315.     next_row2:
  316.       ptr += 2 * ewidth;
  317.     }
  318.       
  319.       return;
  320.     }
  321.  
  322.   g_warning ("update_tile_rowhints: Don't know about tiles with bpp==%d", bpp);
  323. }
  324.  
  325.  
  326. static unsigned char *
  327. paint_funcs_get_buffer (int size)
  328. {
  329.   if (size > tmp_buffer_size)
  330.     {
  331.       tmp_buffer_size = size;
  332.       tmp_buffer = (unsigned char *) g_realloc (tmp_buffer, size);
  333.     }
  334.  
  335.   return tmp_buffer;
  336. }
  337.  
  338.  
  339. /*
  340.  * The equations: g(r) = exp (- r^2 / (2 * sigma^2))
  341.  *                   r = sqrt (x^2 + y ^2)
  342.  */
  343.  
  344. static int *
  345. make_curve (double  sigma,
  346.         int    *length)
  347. {
  348.   int *curve;
  349.   double sigma2;
  350.   double l;
  351.   int temp;
  352.   int i, n;
  353.  
  354.   sigma2 = 2 * sigma * sigma;
  355.   l = sqrt (-sigma2 * log (1.0 / 255.0));
  356.  
  357.   n = ceil (l) * 2;
  358.   if ((n % 2) == 0)
  359.     n += 1;
  360.  
  361.   curve = g_malloc (sizeof (int) * n);
  362.  
  363.   *length = n / 2;
  364.   curve += *length;
  365.   curve[0] = 255;
  366.  
  367.   for (i = 1; i <= *length; i++)
  368.     {
  369.       temp = (int) (exp (- (i * i) / sigma2) * 255);
  370.       curve[-i] = temp;
  371.       curve[i] = temp;
  372.     }
  373.  
  374.   return curve;
  375. }
  376.  
  377.  
  378. static void
  379. run_length_encode (unsigned char *src,
  380.            int           *dest,
  381.            int            w,
  382.            int            bytes)
  383. {
  384.   int start;
  385.   int i;
  386.   int j;
  387.   unsigned char last;
  388.  
  389.   last = *src;
  390.   src += bytes;
  391.   start = 0;
  392.  
  393.   for (i = 1; i < w; i++)
  394.     {
  395.       if (*src != last)
  396.     {
  397.       for (j = start; j < i; j++)
  398.         {
  399.           *dest++ = (i - j);
  400.           *dest++ = last;
  401.         }
  402.       start = i;
  403.       last = *src;
  404.     }
  405.       src += bytes;
  406.     }
  407.  
  408.   for (j = start; j < i; j++)
  409.     {
  410.       *dest++ = (i - j);
  411.       *dest++ = last;
  412.     }
  413. }
  414.  
  415. /* Note: cubic function no longer clips result */
  416. static inline double
  417. cubic (double dx,
  418.        int    jm1,
  419.        int    j,
  420.        int    jp1,
  421.        int    jp2)
  422. {
  423.  
  424.   /* Catmull-Rom - not bad */
  425.   return (double) ((( ( - jm1 + 3 * j - 3 * jp1 + jp2 ) * dx +
  426.           ( 2 * jm1 - 5 * j + 4 * jp1 - jp2 ) ) * dx +
  427.           ( - jm1 + jp1 ) ) * dx + (j + j) ) / 2.0;
  428. }
  429.  
  430. /*********************/
  431. /*  FUNCTIONS        */
  432. /*********************/
  433.  
  434. void
  435. paint_funcs_setup ()
  436. {
  437.   int i;
  438.  
  439.   /*  allocate the temporary buffer  */
  440.   tmp_buffer = (unsigned char *) g_malloc (STD_BUF_SIZE);
  441.   tmp_buffer_size = STD_BUF_SIZE;
  442.  
  443.   /*  initialize the color hash table--invalidate all entries  */
  444.   for (i = 0; i < HASH_TABLE_SIZE; i++)
  445.     color_hash_table[i].gimage = NULL;
  446.   color_hash_misses = 0;
  447.   color_hash_hits = 0;
  448.  
  449.   /*  generate a table of random seeds  */
  450.   srand (RANDOM_SEED);
  451.  
  452.   /* FIXME: Why creating an array of random values and shuffle it randomly
  453.    * afterwards??? 
  454.    */
  455.   
  456.   for (i = 0; i < RANDOM_TABLE_SIZE; i++)
  457.     random_table[i] = rand ();
  458.  
  459.   for (i = 0; i < RANDOM_TABLE_SIZE; i++)
  460.     {
  461.       int tmp;
  462.       int swap = i + rand () % (RANDOM_TABLE_SIZE - i);
  463.       tmp = random_table[i];
  464.       random_table[i] = random_table[swap];
  465.       random_table[swap] = tmp;
  466.     }
  467.  
  468.   for (i = 0; i < 256; i++)
  469.     add_lut[i] = i; 
  470.      
  471.   for (i = 256; i <= 510; i++)
  472.     add_lut[i] = 255; 
  473. }
  474.  
  475.  
  476. void
  477. paint_funcs_free ()
  478. {
  479.   /*  free the temporary buffer  */
  480.   g_free (tmp_buffer);
  481.  
  482.   /*  print out the hash table statistics
  483.       printf ("RGB->indexed hash table lookups: %d\n", color_hash_hits + color_hash_misses);
  484.       printf ("RGB->indexed hash table hits: %d\n", color_hash_hits);
  485.       printf ("RGB->indexed hash table misses: %d\n", color_hash_misses);
  486.       printf ("RGB->indexed hash table hit rate: %f\n",
  487.       100.0 * color_hash_hits / (color_hash_hits + color_hash_misses));
  488.       */
  489. }
  490.  
  491. void
  492. paint_funcs_invalidate_color_hash_table (GimpImage* gimage,
  493.                      gint       index)
  494. {
  495.   gint i;
  496.  
  497.   g_return_if_fail (gimage != NULL);
  498.  
  499.   if (index == -1) /* invalidate all entries */
  500.     {
  501.       for (i = 0; i < HASH_TABLE_SIZE; i++)
  502.     if (color_hash_table[i].gimage == gimage)
  503.       color_hash_table[i].gimage = NULL;
  504.     }
  505.   else
  506.     {
  507.       for (i = 0; i < HASH_TABLE_SIZE; i++)
  508.     if (color_hash_table[i].gimage == gimage && 
  509.         color_hash_table[i].index  == index)
  510.       color_hash_table[i].gimage = NULL;      
  511.     }
  512. }
  513.  
  514.  
  515. void
  516. color_pixels (unsigned char *dest,
  517.           const unsigned char *color,
  518.           int            w,
  519.           int            bytes)
  520. {
  521.   /* dest % bytes and color % bytes must be 0 or we will crash 
  522.      when bytes = 2 or 4.
  523.      Is this safe to assume?  Lets find out.
  524.      This is 4-7X as fast as the simple version.
  525.      */
  526.  
  527. #if defined(sparc) || defined(__sparc__)
  528.   register unsigned char c0, c1, c2, c3;
  529. #else
  530.   register unsigned char c0, c1, c2;
  531.   register guint32 *longd, longc;
  532.   register guint16 *shortd, shortc;
  533. #endif
  534.  
  535.   switch (bytes)
  536.   {
  537.    case 1:
  538.      memset(dest, *color, w);
  539.      break;
  540.  
  541.    case 2:
  542. #if defined(sparc) || defined(__sparc__)
  543.      c0 = color[0];
  544.      c1 = color[1];
  545.      while (w--)
  546.        {
  547.      dest[0] = c0;
  548.      dest[1] = c1;
  549.      dest += 2;
  550.        }
  551. #else
  552.      shortc = ((guint16 *)color)[0];
  553.      shortd = (guint16 *)dest;
  554.      while (w--)
  555.        {
  556.      *shortd = shortc;
  557.      shortd++;
  558.        }
  559. #endif /* sparc || __sparc__ */
  560.      break;
  561.    case 3:
  562.      c0 = color[0];
  563.      c1 = color[1];
  564.      c2 = color[2];
  565.      while (w--)
  566.        {
  567.      dest[0] = c0;
  568.      dest[1] = c1;
  569.      dest[2] = c2;
  570.      dest += 3;
  571.        }
  572.      break;
  573.    case 4:
  574. #if defined(sparc) || defined(__sparc__)
  575.      c0 = color[0];
  576.      c1 = color[1];
  577.      c2 = color[2];
  578.      c3 = color[3];
  579.      while (w--)
  580.        {
  581.      dest[0] = c0;
  582.      dest[1] = c1;
  583.      dest[2] = c2;
  584.      dest[3] = c3;
  585.      dest += 4;
  586.        }
  587. #else
  588.      longc = ((guint32 *)color)[0];
  589.      longd = (guint32 *)dest;
  590.      while (w--)
  591.        {
  592.      *longd = longc;
  593.      longd++;
  594.        }
  595. #endif /* sparc || __sparc__ */
  596.      break;
  597.    default:
  598.      while (w--)
  599.        {
  600.          memcpy (dest, color, bytes);
  601.          dest += bytes;
  602.        }
  603.   }
  604. }
  605.  
  606.  
  607. void
  608. blend_pixels (const unsigned char *src1,
  609.           const unsigned char *src2,
  610.           unsigned char *dest,
  611.           int            blend,
  612.           int            w,
  613.           int            bytes,
  614.           int            has_alpha)
  615. {
  616.   int b;
  617.   unsigned char blend2 = (255 - blend);
  618.  
  619.   while (w --)
  620.     {
  621.       for (b = 0; b < bytes; b++)
  622.     dest[b] = (src1[b] * blend2 + src2[b] * blend) / 255;
  623.  
  624.       src1 += bytes;
  625.       src2 += bytes;
  626.       dest += bytes;
  627.     }
  628. }
  629.  
  630.  
  631. void
  632. shade_pixels (const unsigned char *src,
  633.           unsigned char *dest,
  634.           const unsigned char *col,
  635.           int            blend,
  636.           int            w,
  637.           int            bytes,
  638.           int            has_alpha)
  639. {
  640.   int alpha, b;
  641.   unsigned char blend2 = (255 - blend);
  642.  
  643.   alpha = (has_alpha) ? bytes - 1 : bytes;
  644.   while (w --)
  645.     {
  646.       for (b = 0; b < alpha; b++)
  647.     dest[b] = (src[b] * blend2 + col[b] * blend) / 255;
  648.  
  649.       if (has_alpha)
  650.     dest[alpha] = src[alpha];  /* alpha channel */
  651.  
  652.       src += bytes;
  653.       dest += bytes;
  654.     }
  655. }
  656.  
  657.  
  658. void
  659. extract_alpha_pixels (const unsigned char *src,
  660.               const unsigned char *mask,
  661.               unsigned char *dest,
  662.               int            w,
  663.               int            bytes)
  664. {
  665.   const unsigned char * m;
  666.   int tmp;
  667.  
  668.   const int alpha = bytes - 1;
  669.   
  670.   if (mask)
  671.     {
  672.       m = mask;
  673.       while (w --)
  674.         {
  675.           *dest++ = INT_MULT(src[alpha], *m, tmp);
  676.           m++;
  677.           src += bytes;
  678.         }
  679.      }  else
  680.      { 
  681.        m = &no_mask;
  682.        while (w --)
  683.         { 
  684.           *dest++ = INT_MULT(src[alpha], *m, tmp);
  685.           src += bytes;
  686.         }
  687.      }
  688. }
  689.  
  690. void
  691. darken_pixels (const unsigned char *src1,
  692.            const unsigned char *src2,
  693.            unsigned char *dest,
  694.            int            length,
  695.            int            bytes1,
  696.            int            bytes2,
  697.            int            has_alpha1,
  698.            int            has_alpha2)
  699. {
  700.   int b, alpha;
  701.   unsigned char s1, s2;
  702.  
  703.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  704.  
  705.   while (length--)
  706.     {
  707.       for (b = 0; b < alpha; b++)
  708.     {
  709.       s1 = src1[b];
  710.       s2 = src2[b];
  711.       dest[b] = (s1 < s2) ? s1 : s2;
  712.     }
  713.  
  714.       if (has_alpha1 && has_alpha2)
  715.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  716.       else if (has_alpha2)
  717.     dest[alpha] = src2[alpha];
  718.  
  719.       src1 += bytes1;
  720.       src2 += bytes2;
  721.       dest += bytes2;
  722.     }
  723. }
  724.  
  725.  
  726. void
  727. lighten_pixels (const unsigned char *src1,
  728.         const unsigned char *src2,
  729.         unsigned char *dest,
  730.         int            length,
  731.         int            bytes1,
  732.         int            bytes2,
  733.         int            has_alpha1,
  734.         int            has_alpha2)
  735. {
  736.   int b, alpha;
  737.   unsigned char s1, s2;
  738.  
  739.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  740.  
  741.   while (length--)
  742.     {
  743.       for (b = 0; b < alpha; b++)
  744.     {
  745.       s1 = src1[b];
  746.       s2 = src2[b];
  747.       dest[b] = (s1 < s2) ? s2 : s1;
  748.     }
  749.  
  750.       if (has_alpha1 && has_alpha2)
  751.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  752.       else if (has_alpha2)
  753.     dest[alpha] = src2[alpha];
  754.  
  755.       src1 += bytes1;
  756.       src2 += bytes2;
  757.       dest += bytes2;
  758.     }
  759. }
  760.  
  761.  
  762. void
  763. hsv_only_pixels (const unsigned char *src1,
  764.          const unsigned char *src2,
  765.          unsigned char *dest,
  766.          int            mode,
  767.          int            length,
  768.          int            bytes1,
  769.          int            bytes2,
  770.          int            has_alpha1,
  771.          int            has_alpha2)
  772. {
  773.   int r1, g1, b1;
  774.   int r2, g2, b2;
  775.  
  776.   /*  assumes inputs are only 4 byte RGBA pixels  */
  777.   while (length--)
  778.     {
  779.       r1 = src1[0]; g1 = src1[1]; b1 = src1[2];
  780.       r2 = src2[0]; g2 = src2[1]; b2 = src2[2];
  781.       gimp_rgb_to_hsv (&r1, &g1, &b1);
  782.       gimp_rgb_to_hsv (&r2, &g2, &b2);
  783.  
  784.       switch (mode)
  785.     {
  786.     case HUE_MODE:
  787.       r1 = r2;
  788.       break;
  789.     case SATURATION_MODE:
  790.       g1 = g2;
  791.       break;
  792.     case VALUE_MODE:
  793.       b1 = b2;
  794.       break;
  795.     }
  796.  
  797.       /*  set the destination  */
  798.       gimp_hsv_to_rgb (&r1, &g1, &b1);
  799.  
  800.       dest[0] = r1; dest[1] = g1; dest[2] = b1;
  801.  
  802.       if (has_alpha1 && has_alpha2)
  803.     dest[3] = MIN (src1[3], src2[3]);
  804.       else if (has_alpha2)
  805.     dest[3] = src2[3];
  806.  
  807.       src1 += bytes1;
  808.       src2 += bytes2;
  809.       dest += bytes2;
  810.     }
  811. }
  812.  
  813.  
  814. void
  815. color_only_pixels (const unsigned char *src1,
  816.            const unsigned char *src2,
  817.            unsigned char *dest,
  818.            int            mode,
  819.            int            length,
  820.            int            bytes1,
  821.            int            bytes2,
  822.            int            has_alpha1,
  823.            int            has_alpha2)
  824. {
  825.   int r1, g1, b1;
  826.   int r2, g2, b2;
  827.  
  828.   /*  assumes inputs are only 4 byte RGBA pixels  */
  829.   while (length--)
  830.     {
  831.       r1 = src1[0]; g1 = src1[1]; b1 = src1[2];
  832.       r2 = src2[0]; g2 = src2[1]; b2 = src2[2];
  833.       gimp_rgb_to_hls (&r1, &g1, &b1);
  834.       gimp_rgb_to_hls (&r2, &g2, &b2);
  835.  
  836.       /*  transfer hue and saturation to the source pixel  */
  837.       r1 = r2;
  838.       b1 = b2;
  839.  
  840.       /*  set the destination  */
  841.       gimp_hls_to_rgb (&r1, &g1, &b1);
  842.  
  843.       dest[0] = r1; dest[1] = g1; dest[2] = b1;
  844.  
  845.       if (has_alpha1 && has_alpha2)
  846.     dest[3] = MIN (src1[3], src2[3]);
  847.       else if (has_alpha2)
  848.     dest[3] = src2[3];
  849.  
  850.       src1 += bytes1;
  851.       src2 += bytes2;
  852.       dest += bytes2;
  853.     }
  854. }
  855.  
  856. void
  857. multiply_pixels (const unsigned char *src1,
  858.          const unsigned char *src2,
  859.          unsigned char *dest,
  860.          int            length,
  861.          int            bytes1,
  862.          int            bytes2,
  863.          int            has_alpha1,
  864.          int            has_alpha2)
  865. {
  866.   int alpha, b;
  867.   int tmp;
  868.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  869.  
  870.   if (has_alpha1 && has_alpha2)
  871.     while (length --)
  872.     {
  873.       for (b = 0; b < alpha; b++)
  874.     dest[b] = INT_MULT(src1[b], src2[b], tmp);
  875.  
  876.       dest[alpha] = MIN (src1[alpha], src2[alpha]);
  877.  
  878.       src1 += bytes1;
  879.       src2 += bytes2;
  880.       dest += bytes2;
  881.     }
  882.   else if (has_alpha2)
  883.     while (length --)
  884.     {
  885.       for (b = 0; b < alpha; b++)
  886.     dest[b] = INT_MULT(src1[b], src2[b], tmp);
  887.  
  888.       dest[alpha] = src2[alpha];
  889.  
  890.       src1 += bytes1;
  891.       src2 += bytes2;
  892.       dest += bytes2;
  893.     }
  894.   else
  895.     while (length --)
  896.     {
  897.       for (b = 0; b < alpha; b++)
  898.     dest[b] = INT_MULT(src1[b], src2[b], tmp);
  899.  
  900.       src1 += bytes1;
  901.       src2 += bytes2;
  902.       dest += bytes2;
  903.     }
  904. }
  905.  
  906.  
  907. void
  908. divide_pixels (const unsigned char *src1,
  909.          const unsigned char *src2,
  910.          unsigned char *dest,
  911.          int            length,
  912.          int            bytes1,
  913.          int            bytes2,
  914.          int            has_alpha1,
  915.          int            has_alpha2)
  916. {
  917.   int alpha, b, result;
  918.  
  919.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  920.  
  921.   while (length --)
  922.     {
  923.       for (b = 0; b < alpha; b++)
  924.     {
  925.       result = ((src1[b] * 256) / (1+src2[b]));
  926.       dest[b] = MIN (result, 255);
  927.     }
  928.  
  929.       if (has_alpha1 && has_alpha2)
  930.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  931.       else if (has_alpha2)
  932.     dest[alpha] = src2[alpha];
  933.  
  934.       src1 += bytes1;
  935.       src2 += bytes2;
  936.       dest += bytes2;
  937.     }
  938. }
  939.  
  940.  
  941. void
  942. screen_pixels (const unsigned char *src1,
  943.            const unsigned char *src2,
  944.            unsigned char *dest,
  945.            int            length,
  946.            int            bytes1,
  947.            int            bytes2,
  948.            int            has_alpha1,
  949.            int            has_alpha2)
  950. {
  951.   int alpha, b;
  952.   int tmp;
  953.  
  954.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  955.  
  956.   while (length --)
  957.     {
  958.       for (b = 0; b < alpha; b++)
  959.     dest[b] = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp);
  960.  
  961.       if (has_alpha1 && has_alpha2)
  962.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  963.       else if (has_alpha2)
  964.     dest[alpha] = src2[alpha];
  965.  
  966.       src1 += bytes1;
  967.       src2 += bytes2;
  968.       dest += bytes2;
  969.     }
  970. }
  971.  
  972.  
  973. void
  974. overlay_pixels (const unsigned char *src1,
  975.         const unsigned char *src2,
  976.         unsigned char *dest,
  977.         int            length,
  978.         int            bytes1,
  979.         int            bytes2,
  980.         int            has_alpha1,
  981.         int            has_alpha2)
  982. {
  983.   int alpha, b;
  984.   int tmp;
  985.  
  986.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  987.  
  988.   while (length --)
  989.     {
  990.       for (b = 0; b < alpha; b++)
  991.     {
  992.       dest[b] = INT_MULT(src1[b], src1[b] + INT_MULT(2 * src2[b],
  993.                              255 - src1[b],
  994.                              tmp), tmp);
  995.     }
  996.  
  997.       if (has_alpha1 && has_alpha2)
  998.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  999.       else if (has_alpha2)
  1000.     dest[alpha] = src2[alpha];
  1001.  
  1002.       src1 += bytes1;
  1003.       src2 += bytes2;
  1004.       dest += bytes2;
  1005.     }
  1006. }
  1007.  
  1008.  
  1009. void
  1010. add_pixels (const unsigned char *src1,
  1011.         const unsigned char *src2,
  1012.         unsigned char *dest,
  1013.         int            length,
  1014.         int            bytes1,
  1015.         int            bytes2,
  1016.         int            has_alpha1,
  1017.         int            has_alpha2)
  1018. {
  1019.   int alpha, b;
  1020.  
  1021.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  1022.  
  1023.   while (length --)
  1024.     {
  1025.       for (b = 0; b < alpha; b++)
  1026.     dest[b] = add_lut[src1[b] + src2[b]];
  1027.  
  1028.       if (has_alpha1 && has_alpha2)
  1029.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1030.       else if (has_alpha2)
  1031.     dest[alpha] = src2[alpha];
  1032.  
  1033.       src1 += bytes1;
  1034.       src2 += bytes2;
  1035.       dest += bytes2;
  1036.     }
  1037. }
  1038.  
  1039.  
  1040. void
  1041. subtract_pixels (const unsigned char *src1,
  1042.          const unsigned char *src2,
  1043.          unsigned char *dest,
  1044.          int            length,
  1045.          int            bytes1,
  1046.          int            bytes2,
  1047.          int            has_alpha1,
  1048.          int            has_alpha2)
  1049. {
  1050.   int alpha, b;
  1051.   int diff;
  1052.  
  1053.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  1054.  
  1055.   while (length --)
  1056.     {
  1057.       for (b = 0; b < alpha; b++)
  1058.     {
  1059.       diff = src1[b] - src2[b];
  1060.       dest[b] = (diff < 0) ? 0 : diff;
  1061.     }
  1062.  
  1063.       if (has_alpha1 && has_alpha2)
  1064.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1065.       else if (has_alpha2)
  1066.     dest[alpha] = src2[alpha];
  1067.  
  1068.       src1 += bytes1;
  1069.       src2 += bytes2;
  1070.       dest += bytes2;
  1071.     }
  1072. }
  1073.  
  1074.  
  1075. void
  1076. difference_pixels (const unsigned char *src1,
  1077.            const unsigned char *src2,
  1078.            unsigned char *dest,
  1079.            int            length,
  1080.            int            bytes1,
  1081.            int            bytes2,
  1082.            int            has_alpha1,
  1083.            int            has_alpha2)
  1084. {
  1085.   int alpha, b;
  1086.   int diff;
  1087.  
  1088.   alpha = (has_alpha1 || has_alpha2) ? MAX (bytes1, bytes2) - 1 : bytes1;
  1089.  
  1090.   while (length --)
  1091.     {
  1092.       for (b = 0; b < alpha; b++)
  1093.     {
  1094.       diff = src1[b] - src2[b];
  1095.       dest[b] = (diff < 0) ? -diff : diff;
  1096.     }
  1097.  
  1098.       if (has_alpha1 && has_alpha2)
  1099.     dest[alpha] = MIN (src1[alpha], src2[alpha]);
  1100.       else if (has_alpha2)
  1101.     dest[alpha] = src2[alpha];
  1102.  
  1103.       src1 += bytes1;
  1104.       src2 += bytes2;
  1105.       dest += bytes2;
  1106.     }
  1107. }
  1108.  
  1109.  
  1110. void
  1111. dissolve_pixels (const unsigned char *src,
  1112.          unsigned char *dest,
  1113.          int            x,
  1114.          int            y,
  1115.          int            opacity,
  1116.          int            length,
  1117.          int            sb,
  1118.          int            db,
  1119.          int            has_alpha)
  1120. {
  1121.   int alpha, b;
  1122.   int rand_val;
  1123.   
  1124. #if defined(ENABLE_MP) && defined(__GLIBC__)
  1125.   /* The glibc 2.1 documentation recommends using the SVID random functions
  1126.    * instead of rand_r
  1127.    */
  1128.   struct drand48_data seed;
  1129.   long temp_val;
  1130.  
  1131.   srand48_r (random_table[y % RANDOM_TABLE_SIZE], &seed);
  1132.   for (b = 0; b < x; b++)
  1133.     lrand48_r (&seed, &temp_val);
  1134. #elif defined(ENABLE_MP) && !defined(__GLIBC__)
  1135.   /* If we are running with multiple threads rand_r give _much_ better
  1136.    * performance than rand
  1137.    */
  1138.   unsigned int seed;
  1139.   seed = random_table[y % RANDOM_TABLE_SIZE];
  1140.   for (b = 0; b < x; b++)
  1141.     rand_r (&seed);
  1142. #else
  1143.   /* Set up the random number generator */
  1144.   srand (random_table[y % RANDOM_TABLE_SIZE]);
  1145.   for (b = 0; b < x; b++)
  1146.     rand ();
  1147. #endif
  1148.  
  1149.   alpha = db - 1;
  1150.  
  1151.   while (length--)
  1152.     {
  1153.       /*  preserve the intensity values  */
  1154.       for (b = 0; b < alpha; b++)
  1155.     dest[b] = src[b];
  1156.  
  1157.       /*  dissolve if random value is > opacity  */
  1158. #if defined(ENABLE_MP) && defined(__GLIBC__)
  1159.       lrand48_r (&seed, &temp_val);
  1160.       rand_val = temp_val & 0xff;
  1161. #elif defined(ENABLE_MP) && !defined(__GLIBC__)
  1162.       rand_val = (rand_r (&seed) & 0xff);
  1163. #else
  1164.       rand_val = (rand () & 0xff);
  1165. #endif
  1166.       if (has_alpha)
  1167.     dest[alpha] = (rand_val > src[alpha]) ? 0 : src[alpha];
  1168.       else
  1169.     dest[alpha] = (rand_val > opacity) ? 0 : OPAQUE_OPACITY;
  1170.  
  1171.       dest += db;
  1172.       src  += sb;
  1173.     }
  1174. }
  1175.  
  1176. void
  1177. replace_pixels (unsigned char *src1,
  1178.         unsigned char *src2,
  1179.         unsigned char *dest,
  1180.         unsigned char *mask,
  1181.         int            length,
  1182.         int            opacity,
  1183.         int           *affect,
  1184.         int            bytes1,
  1185.         int            bytes2)
  1186. {
  1187.   int alpha;
  1188.   int b;
  1189.   double a_val, a_recip, mask_val;
  1190.   double norm_opacity;
  1191.   int s1_a, s2_a;
  1192.   int new_val;
  1193.  
  1194.   if (bytes1 != bytes2)
  1195.     {
  1196.       g_warning ("replace_pixels only works on commensurate pixel regions");
  1197.       return;
  1198.     }
  1199.  
  1200.   alpha = bytes1 - 1;
  1201.   norm_opacity = opacity * (1.0 / 65536.0);
  1202.  
  1203.   while (length --)
  1204.     {
  1205.       mask_val = mask[0] * norm_opacity;
  1206.       /* calculate new alpha first. */
  1207.       s1_a = src1[alpha];
  1208.       s2_a = src2[alpha];
  1209.       a_val = s1_a + mask_val * (s2_a - s1_a);
  1210.       if (a_val == 0) /* In any case, write out versions of the blending function */
  1211.                       /* that result when combinations of s1_a, s2_a, and         */
  1212.                   /* mask_val --> 0 (or mask_val -->1)                        */
  1213.         {
  1214.           /* Case 1: s1_a, s2_a, AND mask_val all approach 0+:               */
  1215.       /* Case 2: s1_a AND s2_a both approach 0+, regardless of mask_val: */
  1216.  
  1217.           if(s1_a + s2_a == 0.0)
  1218.             {
  1219.               for (b = 0; b < alpha; b++)
  1220.             {
  1221.                   new_val = 0.5 + (double)src1[b] + mask_val*((double)src2[b] - (double)src1[b]); 
  1222.                   dest[b] = affect[b] ? MIN (new_val, 255) : src1[b];
  1223.                 }
  1224.             }
  1225.  
  1226.       /* Case 3: mask_val AND s1_a both approach 0+, regardless of s2_a  */
  1227.           else if(s1_a + mask_val == 0.0)
  1228.             {
  1229.               for (b = 0; b < alpha; b++)
  1230.             {
  1231.                   dest[b] = src1[b]; 
  1232.                 }
  1233.             }
  1234.  
  1235.       /* Case 4: mask_val -->1 AND s2_a -->0, regardless of s1_a         */
  1236.           else if(1.0 - mask_val + s2_a == 0.0)
  1237.             {
  1238.               for (b = 0; b < alpha; b++)
  1239.             {
  1240.                   dest[b] = affect[b] ? src2[b] : src1[b]; 
  1241.                 }
  1242.             }
  1243.     }
  1244.       else
  1245.     {
  1246.       a_recip = 1.0 / a_val;
  1247.           /* possible optimization: fold a_recip into s1_a and s2_a              */
  1248.           for (b = 0; b < alpha; b++)
  1249.         {
  1250.           new_val = 0.5 + a_recip * (src1[b] * s1_a + mask_val *
  1251.                          (src2[b] * s2_a - src1[b] * s1_a));
  1252.           dest[b] = affect[b] ? MIN (new_val, 255) : src1[b];
  1253.             }
  1254.         }
  1255.       dest[alpha] = affect[alpha] ? a_val + 0.5: s1_a;
  1256.       src1 += bytes1;
  1257.       src2 += bytes2;
  1258.       dest += bytes2;
  1259.       mask++;
  1260.     }
  1261. }
  1262.  
  1263.  
  1264. void
  1265. swap_pixels (unsigned char *src,
  1266.          unsigned char *dest,
  1267.          int            length)
  1268. {
  1269.   while (length--)
  1270.     {
  1271.       *src = *src ^ *dest;
  1272.       *dest = *dest ^ *src;
  1273.       *src = *src ^ *dest;
  1274.       src++;
  1275.       dest++;
  1276.     }
  1277. }
  1278.  
  1279.  
  1280. void
  1281. scale_pixels (const unsigned char *src,
  1282.           unsigned char *dest,
  1283.           int            length,
  1284.           int            scale)
  1285. {
  1286.   int tmp;
  1287.   while (length --)
  1288.   {
  1289.     *dest++ = (unsigned char) INT_MULT(*src,scale,tmp);
  1290.     src++;
  1291.   }
  1292. }
  1293.  
  1294.  
  1295. void
  1296. add_alpha_pixels (const unsigned char *src,
  1297.           unsigned char *dest,
  1298.           int            length,
  1299.           int            bytes)
  1300. {
  1301.   int alpha, b;
  1302.  
  1303.   alpha = bytes + 1;
  1304.   while (length --)
  1305.     {
  1306.       for (b = 0; b < bytes; b++)
  1307.     dest[b] = src[b];
  1308.  
  1309.       dest[b] = OPAQUE_OPACITY;
  1310.  
  1311.       src += bytes;
  1312.       dest += alpha;
  1313.     }
  1314. }
  1315.  
  1316.  
  1317. void
  1318. flatten_pixels (const unsigned char *src,
  1319.         unsigned char *dest,
  1320.         const unsigned char *bg,
  1321.         int            length,
  1322.         int            bytes)
  1323. {
  1324.   int alpha, b;
  1325.   int t1, t2;
  1326.  
  1327.   alpha = bytes - 1;
  1328.   while (length --)
  1329.     {
  1330.       for (b = 0; b < alpha; b++)
  1331.     dest[b] = INT_MULT (src[b], src[alpha], t1) + INT_MULT (bg[b], (255 - src[alpha]), t2);
  1332.  
  1333.       src += bytes;
  1334.       dest += alpha;
  1335.     }
  1336. }
  1337.  
  1338.  
  1339. void
  1340. gray_to_rgb_pixels (const unsigned char *src,
  1341.             unsigned char *dest,
  1342.             int            length,
  1343.             int            bytes)
  1344. {
  1345.   int b;
  1346.   int dest_bytes;
  1347.   int has_alpha;
  1348.  
  1349.   has_alpha = (bytes == 2) ? 1 : 0;
  1350.   dest_bytes = (has_alpha) ? 4 : 3;
  1351.  
  1352.   while (length --)
  1353.     {
  1354.       for (b = 0; b < bytes; b++)
  1355.     dest[b] = src[0];
  1356.  
  1357.       if (has_alpha)
  1358.     dest[3] = src[1];
  1359.  
  1360.       src += bytes;
  1361.       dest += dest_bytes;
  1362.     }
  1363. }
  1364.  
  1365.  
  1366. void
  1367. apply_mask_to_alpha_channel (unsigned char *src,
  1368.                  const unsigned char *mask,
  1369.                  int            opacity,
  1370.                  int            length,
  1371.                  int            bytes)
  1372. {
  1373.   long tmp;
  1374.   src += bytes - 1;
  1375.   if (opacity == 255)
  1376.     while (length --)
  1377.     {
  1378.       *src = INT_MULT(*src, *mask, tmp);
  1379.       mask++;
  1380.       src += bytes;
  1381.     }
  1382.   else
  1383.     while (length --)
  1384.     {
  1385.       *src = INT_MULT3(*src, *mask, opacity, tmp);
  1386.       mask++;
  1387.       src += bytes;
  1388.     }
  1389. }
  1390.  
  1391.  
  1392. void
  1393. combine_mask_and_alpha_channel (unsigned char *src,
  1394.                 const unsigned char *mask,
  1395.                 int            opacity,
  1396.                 int            length,
  1397.                 int            bytes)
  1398. {
  1399.   int mask_val;
  1400.   int alpha;
  1401.   int tmp;
  1402.   alpha = bytes - 1;
  1403.   src += alpha;
  1404.  
  1405.   if (opacity != 255)
  1406.     while (length --)
  1407.     {
  1408.       mask_val = INT_MULT(*mask, opacity, tmp);
  1409.       mask++;
  1410.       *src = *src + INT_MULT((255 - *src) , mask_val, tmp);
  1411.       src += bytes;
  1412.     }
  1413.   else
  1414.     while (length --)
  1415.     {
  1416.       *src = *src + INT_MULT((255 - *src) , *mask, tmp);
  1417.       src += bytes;
  1418.       mask++;
  1419.     }
  1420. }
  1421.  
  1422.  
  1423. void
  1424. copy_gray_to_inten_a_pixels (const unsigned char *src,
  1425.                  unsigned char *dest,
  1426.                  int            length,
  1427.                  int            bytes)
  1428. {
  1429.   int b;
  1430.   int alpha;
  1431.  
  1432.   alpha = bytes - 1;
  1433.   while (length --)
  1434.     {
  1435.       for (b = 0; b < alpha; b++)
  1436.     dest[b] = *src;
  1437.       dest[b] = OPAQUE_OPACITY;
  1438.  
  1439.       src ++;
  1440.       dest += bytes;
  1441.     }
  1442. }
  1443.  
  1444.  
  1445. void
  1446. initial_channel_pixels (const unsigned char *src,
  1447.             unsigned char *dest,
  1448.             int            length,
  1449.             int            bytes)
  1450. {
  1451.   int alpha, b;
  1452.  
  1453.   alpha = bytes - 1;
  1454.   while (length --)
  1455.     {
  1456.       for (b = 0; b < alpha; b++)
  1457.     dest[b] = src[0];
  1458.  
  1459.       dest[alpha] = OPAQUE_OPACITY;
  1460.  
  1461.       dest += bytes;
  1462.       src ++;
  1463.     }
  1464. }
  1465.  
  1466.  
  1467. void
  1468. initial_indexed_pixels (const unsigned char *src,
  1469.             unsigned char *dest,
  1470.             const unsigned char *cmap,
  1471.             int            length)
  1472. {
  1473.   int col_index;
  1474.  
  1475.   /*  This function assumes always that we're mapping from
  1476.    *  an RGB colormap to an RGBA image...
  1477.    */
  1478.   while (length--)
  1479.     {
  1480.       col_index = *src++ * 3;
  1481.       *dest++ = cmap[col_index++];
  1482.       *dest++ = cmap[col_index++];
  1483.       *dest++ = cmap[col_index++];
  1484.       *dest++ = OPAQUE_OPACITY;
  1485.     }
  1486. }
  1487.  
  1488.  
  1489. void
  1490. initial_indexed_a_pixels (const unsigned char *src,
  1491.               unsigned char *dest,
  1492.               const unsigned char *mask,
  1493.               const unsigned char *cmap,
  1494.               int            opacity,
  1495.               int            length)
  1496. {
  1497.   int col_index;
  1498.   unsigned char new_alpha;
  1499.   const unsigned char * m;
  1500.   long tmp;
  1501.   if (mask)
  1502.     m = mask;
  1503.   else
  1504.     m = &no_mask;
  1505.  
  1506.   while (length --)
  1507.     {
  1508.       col_index = *src++ * 3;
  1509.       new_alpha = INT_MULT3(*src, *m, opacity, tmp);
  1510.       src++;
  1511.       *dest++ = cmap[col_index++];
  1512.       *dest++ = cmap[col_index++];
  1513.       *dest++ = cmap[col_index++];
  1514.       /*  Set the alpha channel  */
  1515.       *dest++ = (new_alpha > 127) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
  1516.  
  1517.       if (mask)
  1518.     m++;
  1519.     }
  1520. }
  1521.  
  1522.  
  1523. void
  1524. initial_inten_pixels (const unsigned char *src,
  1525.               unsigned char *dest,
  1526.               const unsigned char *mask,
  1527.               int            opacity,
  1528.               const int     *affect,
  1529.               int            length,
  1530.               int            bytes)
  1531. {
  1532.   int b;
  1533.   const unsigned char * m;
  1534.   int tmp;
  1535.   int l;
  1536.   unsigned char *destp;
  1537.   const unsigned char *srcp;
  1538.   const int dest_bytes = bytes + 1;
  1539.  
  1540.   if (mask)
  1541.   {
  1542.     m = mask;
  1543.     
  1544.     /*  This function assumes the source has no alpha channel and
  1545.      *  the destination has an alpha channel.  So dest_bytes = bytes + 1
  1546.      */
  1547.    
  1548.     if (bytes == 3 && affect[0] && affect[1] && affect[2])
  1549.     {
  1550.       if (!affect[bytes])
  1551.     opacity = 0;
  1552.       destp = dest + bytes;
  1553.       if (opacity != 0)
  1554.     while(length--)
  1555.     {
  1556.       dest[0] = src[0];
  1557.       dest[1] = src[1];
  1558.       dest[2] = src[2];
  1559.       dest[3] = INT_MULT(opacity, *m, tmp);
  1560.       src  += bytes;
  1561.       dest += dest_bytes;
  1562.       m++;
  1563.     }
  1564.       else
  1565.     while(length--)
  1566.     {
  1567.       dest[0] = src[0];
  1568.       dest[1] = src[1];
  1569.       dest[2] = src[2];
  1570.       dest[3] = opacity;
  1571.       src  += bytes;
  1572.       dest += dest_bytes;
  1573.     }
  1574.       return;
  1575.     }
  1576.     for (b =0; b < bytes; b++)
  1577.     {
  1578.       destp = dest + b;
  1579.       srcp = src + b;
  1580.       l = length;
  1581.       if (affect[b])
  1582.     while(l--)
  1583.     {
  1584.       *destp = *srcp;
  1585.       srcp  += bytes;
  1586.       destp += dest_bytes;
  1587.     }
  1588.       else
  1589.     while(l--)
  1590.     {
  1591.       *destp = 0;
  1592.       destp += dest_bytes;
  1593.     }
  1594.     }
  1595.  
  1596.     /* fill the alpha channel */ 
  1597.     if (!affect[bytes])
  1598.       opacity = 0;
  1599.     destp = dest + bytes;
  1600.     if (opacity != 0)
  1601.       while (length--)
  1602.       {
  1603.     *destp = INT_MULT(opacity , *m, tmp);
  1604.     destp += dest_bytes;
  1605.     m++;
  1606.       }
  1607.     else
  1608.       while (length--)
  1609.       {
  1610.     *destp = opacity;
  1611.     destp += dest_bytes;
  1612.       }
  1613.   }
  1614.  
  1615.   /* If no mask */
  1616.   else
  1617.   {
  1618.     m = &no_mask;
  1619.  
  1620.     /*  This function assumes the source has no alpha channel and
  1621.      *  the destination has an alpha channel.  So dest_bytes = bytes + 1
  1622.      */
  1623.     
  1624.     if (bytes == 3 && affect[0] && affect[1] && affect[2])
  1625.       {
  1626.     if (!affect[bytes])
  1627.       opacity = 0;
  1628.     destp = dest + bytes;
  1629.     while(length--)
  1630.       {
  1631.         dest[0] = src[0];
  1632.         dest[1] = src[1];
  1633.         dest[2] = src[2];
  1634.         dest[3] = opacity;
  1635.         src  += bytes;
  1636.         dest += dest_bytes;
  1637.       }
  1638.     return;
  1639.       }
  1640.     
  1641.     for (b =0; b < bytes; b++)
  1642.       {
  1643.     destp = dest + b;
  1644.     srcp = src + b;
  1645.     l = length;
  1646.     if (affect[b])
  1647.       while(l--)
  1648.         {
  1649.           *destp = *srcp;
  1650.           srcp  += bytes;
  1651.           destp += dest_bytes;
  1652.         }
  1653.     else
  1654.       while(l--)
  1655.         {
  1656.           *destp = 0;
  1657.           destp += dest_bytes;
  1658.         }
  1659.       }
  1660.  
  1661.     /* fill the alpha channel */ 
  1662.     if (!affect[bytes])
  1663.       opacity = 0;
  1664.     destp = dest + bytes;
  1665.     while (length--)
  1666.       {
  1667.     *destp = opacity;
  1668.     destp += dest_bytes;
  1669.       }
  1670.   }
  1671. }
  1672.  
  1673.  
  1674. void
  1675. initial_inten_a_pixels (const unsigned char *src,
  1676.             unsigned char       *dest,
  1677.             const unsigned char *mask,
  1678.             int                  opacity,
  1679.             const int           *affect,
  1680.             int                  length,
  1681.             int                  bytes)
  1682. {
  1683.   int alpha, b;
  1684.   const unsigned char * m;
  1685.   long tmp;
  1686.  
  1687.   alpha = bytes - 1;
  1688.   if (mask)
  1689.     {
  1690.       m = mask;
  1691.       while (length --)
  1692.     {
  1693.       for (b = 0; b < alpha; b++)
  1694.         dest[b] = src[b] * affect[b];
  1695.       
  1696.       /*  Set the alpha channel  */
  1697.       dest[alpha] = affect [alpha] ? INT_MULT3(opacity, src[alpha], *m, tmp)
  1698.         : 0;
  1699.       
  1700.       m++;
  1701.       
  1702.       dest += bytes;
  1703.       src += bytes;
  1704.     }
  1705.     }
  1706.   else
  1707.     {
  1708.       while (length --)
  1709.     {
  1710.       for (b = 0; b < alpha; b++)
  1711.         dest[b] = src[b] * affect[b];
  1712.       
  1713.       /*  Set the alpha channel  */
  1714.       dest[alpha] = affect [alpha] ? INT_MULT(opacity , src[alpha], tmp) : 0;
  1715.       
  1716.       dest += bytes;
  1717.       src += bytes;
  1718.     }
  1719.     }
  1720. }
  1721.  
  1722.  
  1723. void
  1724. combine_indexed_and_indexed_pixels (const unsigned char *src1,
  1725.                     const unsigned char *src2,
  1726.                     unsigned char       *dest,
  1727.                     const unsigned char *mask,
  1728.                     int                  opacity,
  1729.                     const int           *affect,
  1730.                     int                  length,
  1731.                     int                  bytes)
  1732. {
  1733.   int b;
  1734.   unsigned char new_alpha;
  1735.   const unsigned char * m;
  1736.   int tmp;
  1737.   if (mask)
  1738.     {
  1739.       m = mask;
  1740.       while (length --)
  1741.     {
  1742.       new_alpha = INT_MULT(*m , opacity, tmp);
  1743.       
  1744.       for (b = 0; b < bytes; b++)
  1745.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1746.       
  1747.       m++;
  1748.       
  1749.       src1 += bytes;
  1750.       src2 += bytes;
  1751.       dest += bytes;
  1752.     }
  1753.     }
  1754.   else
  1755.     {
  1756.       while (length --)
  1757.     {
  1758.       new_alpha = opacity;
  1759.       
  1760.       for (b = 0; b < bytes; b++)
  1761.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1762.       
  1763.       src1 += bytes;
  1764.       src2 += bytes;
  1765.       dest += bytes;
  1766.     }
  1767.     }
  1768. }
  1769.  
  1770.  
  1771. void
  1772. combine_indexed_and_indexed_a_pixels (const unsigned char *src1,
  1773.                       const unsigned char *src2,
  1774.                       unsigned char       *dest,
  1775.                       const unsigned char *mask,
  1776.                       int                  opacity,
  1777.                       const int           *affect,
  1778.                       int                  length,
  1779.                       int                  bytes)
  1780. {
  1781.   int b, alpha;
  1782.   unsigned char new_alpha;
  1783.   const unsigned char * m;
  1784.   int src2_bytes;
  1785.   long tmp;
  1786.   alpha = 1;
  1787.   src2_bytes = 2;
  1788.  
  1789.   if (mask)
  1790.     {
  1791.       m = mask;
  1792.       while (length --)
  1793.     {
  1794.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  1795.  
  1796.       for (b = 0; b < bytes; b++)
  1797.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1798.  
  1799.       m++;
  1800.  
  1801.       src1 += bytes;
  1802.       src2 += src2_bytes;
  1803.       dest += bytes;
  1804.     }
  1805.     }
  1806.   else
  1807.     {
  1808.       while (length --)
  1809.     {
  1810.       new_alpha = INT_MULT(src2[alpha], opacity, tmp);
  1811.  
  1812.       for (b = 0; b < bytes; b++)
  1813.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1814.  
  1815.       src1 += bytes;
  1816.       src2 += src2_bytes;
  1817.       dest += bytes;
  1818.     }
  1819.     }
  1820. }
  1821.  
  1822.  
  1823. void
  1824. combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1,
  1825.                     const unsigned char *src2,
  1826.                     unsigned char       *dest,
  1827.                     const unsigned char *mask,
  1828.                     int                  opacity,
  1829.                     const int           *affect,
  1830.                     int                  length,
  1831.                     int                  bytes)
  1832. {
  1833.   int b, alpha;
  1834.   unsigned char new_alpha;
  1835.   const unsigned char * m;
  1836.   long tmp;
  1837.  
  1838.   alpha = 1;
  1839.  
  1840.   if (mask)
  1841.     {
  1842.       m = mask;
  1843.       while (length --)
  1844.     {
  1845.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  1846.  
  1847.       for (b = 0; b < alpha; b++)
  1848.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1849.  
  1850.       dest[alpha] = (affect[alpha] && new_alpha > 127) ? OPAQUE_OPACITY : src1[alpha];
  1851.  
  1852.       m++;
  1853.  
  1854.       src1 += bytes;
  1855.       src2 += bytes;
  1856.       dest += bytes;
  1857.     }
  1858.     }
  1859.   else
  1860.     {
  1861.       while (length --)
  1862.     {
  1863.       new_alpha = INT_MULT(src2[alpha], opacity, tmp);
  1864.  
  1865.       for (b = 0; b < alpha; b++)
  1866.         dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b];
  1867.  
  1868.       dest[alpha] = (affect[alpha] && new_alpha > 127) ? OPAQUE_OPACITY : src1[alpha];
  1869.  
  1870.       src1 += bytes;
  1871.       src2 += bytes;
  1872.       dest += bytes;
  1873.     }
  1874.     }
  1875. }
  1876.  
  1877.  
  1878. void
  1879. combine_inten_a_and_indexed_a_pixels (const unsigned char *src1,
  1880.                       const unsigned char *src2,
  1881.                       unsigned char       *dest,
  1882.                       const unsigned char *mask,
  1883.                       const unsigned char *cmap,
  1884.                       int                  opacity,
  1885.                       int                  length,
  1886.                       int                  bytes)
  1887. {
  1888.   int b, alpha;
  1889.   unsigned char new_alpha;
  1890.   int src2_bytes;
  1891.   int index;
  1892.   long tmp;
  1893.  
  1894.   alpha = 1;
  1895.   src2_bytes = 2;
  1896.  
  1897.   if (mask)
  1898.     {
  1899.       const unsigned char *m = mask;
  1900.       while (length --)
  1901.     {
  1902.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  1903.  
  1904.       index = src2[0] * 3;
  1905.  
  1906.       for (b = 0; b < bytes-1; b++)
  1907.         dest[b] = (new_alpha > 127) ? cmap[index + b] : src1[b];
  1908.  
  1909.       dest[b] = (new_alpha > 127) ? OPAQUE_OPACITY : src1[b];  /*  alpha channel is opaque  */
  1910.  
  1911.       m++;
  1912.  
  1913.       src1 += bytes;
  1914.       src2 += src2_bytes;
  1915.       dest += bytes;
  1916.     }
  1917.     }
  1918.   else
  1919.     {
  1920.       while (length --)
  1921.     {
  1922.       new_alpha = INT_MULT(src2[alpha], opacity, tmp);
  1923.  
  1924.       index = src2[0] * 3;
  1925.  
  1926.       for (b = 0; b < bytes-1; b++)
  1927.         dest[b] = (new_alpha > 127) ? cmap[index + b] : src1[b];
  1928.  
  1929.       dest[b] = (new_alpha > 127) ? OPAQUE_OPACITY : src1[b];  /*  alpha channel is opaque  */
  1930.  
  1931.       /* m++; /Per */
  1932.  
  1933.       src1 += bytes;
  1934.       src2 += src2_bytes;
  1935.       dest += bytes;
  1936.     }
  1937.     }
  1938. }
  1939.  
  1940.  
  1941. void
  1942. combine_inten_and_inten_pixels (const unsigned char *src1,
  1943.                 const unsigned char *src2,
  1944.                 unsigned char       *dest,
  1945.                 const unsigned char *mask,
  1946.                 int                  opacity,
  1947.                 const int           *affect,
  1948.                 int                  length,
  1949.                 int                  bytes)
  1950. {
  1951.   int b;
  1952.   unsigned char new_alpha;
  1953.   const unsigned char * m;
  1954.   int tmp;
  1955.   if (mask)
  1956.     {
  1957.       m = mask;
  1958.       while (length --)
  1959.     {
  1960.       new_alpha = INT_MULT(*m, opacity, tmp);
  1961.  
  1962.       for (b = 0; b < bytes; b++)
  1963.         dest[b] = (affect[b]) ?
  1964.           INT_BLEND(src2[b], src1[b], new_alpha, tmp) :
  1965.         src1[b];
  1966.  
  1967.       m++;
  1968.  
  1969.       src1 += bytes;
  1970.       src2 += bytes;
  1971.       dest += bytes;
  1972.     }
  1973.     }
  1974.   else
  1975.     {
  1976.       while (length --)
  1977.     {
  1978.  
  1979.       for (b = 0; b < bytes; b++)
  1980.         dest[b] = (affect[b]) ?
  1981.           INT_BLEND(src2[b], src1[b], opacity, tmp) :
  1982.         src1[b];
  1983.  
  1984.       src1 += bytes;
  1985.       src2 += bytes;
  1986.       dest += bytes;
  1987.     }
  1988.     }
  1989. }
  1990.  
  1991.  
  1992. void
  1993. combine_inten_and_inten_a_pixels (const unsigned char *src1,
  1994.                   const unsigned char *src2,
  1995.                   unsigned char       *dest,
  1996.                   const unsigned char *mask,
  1997.                   int                  opacity,
  1998.                   const int           *affect,
  1999.                   int                  length,
  2000.                   int                  bytes)
  2001. {
  2002.   int alpha, b;
  2003.   int src2_bytes;
  2004.   unsigned char new_alpha;
  2005.   const unsigned char * m;
  2006.   register long t1;
  2007.   alpha = bytes;
  2008.   src2_bytes = bytes + 1;
  2009.  
  2010.   if (mask)
  2011.     {
  2012.       m = mask;
  2013.       while (length --)
  2014.     {
  2015.       new_alpha = INT_MULT3(src2[alpha], *m, opacity, t1);
  2016.  
  2017.       for (b = 0; b < bytes; b++)
  2018.         dest[b] = (affect[b]) ?
  2019.           INT_BLEND(src2[b], src1[b], new_alpha, t1) :
  2020.           src1[b];
  2021.  
  2022.       m++;
  2023.       src1 += bytes;
  2024.       src2 += src2_bytes;
  2025.       dest += bytes;
  2026.     }
  2027.     }
  2028.   else
  2029.     {
  2030.       if (bytes == 3 && affect[0] && affect[1] && affect[2])
  2031.     while (length --)
  2032.     {
  2033.       new_alpha = INT_MULT(src2[alpha],opacity,t1);
  2034.       dest[0] = INT_BLEND(src2[0] , src1[0] , new_alpha, t1);
  2035.       dest[1] = INT_BLEND(src2[1] , src1[1] , new_alpha, t1);
  2036.       dest[2] = INT_BLEND(src2[2] , src1[2] , new_alpha, t1);
  2037.       src1 += bytes;
  2038.       src2 += src2_bytes;
  2039.       dest += bytes;
  2040.     }
  2041.       else
  2042.     while (length --)
  2043.     {
  2044.       new_alpha = INT_MULT(src2[alpha],opacity,t1);
  2045.       for (b = 0; b < bytes; b++)
  2046.         dest[b] = (affect[b]) ?
  2047.           INT_BLEND(src2[b] , src1[b] , new_alpha, t1) :
  2048.         src1[b];
  2049.  
  2050.       src1 += bytes;
  2051.       src2 += src2_bytes;
  2052.       dest += bytes;
  2053.     }
  2054.     }
  2055. }
  2056.  
  2057. /*orig #define alphify(src2_alpha,new_alpha) \
  2058.     if (new_alpha == 0 || src2_alpha == 0)                            \
  2059.       {                                            \
  2060.         for (b = 0; b < alpha; b++)                                \
  2061.           dest[b] = src1 [b];                                \
  2062.       }                                            \
  2063.     else if (src2_alpha == new_alpha){                            \
  2064.       for (b = 0; b < alpha; b++)                                \
  2065.         dest [b] = affect [b] ? src2 [b] : src1 [b];                    \
  2066.     } else {                                        \
  2067.       ratio = (float) src2_alpha / new_alpha;                        \
  2068.       compl_ratio = 1.0 - ratio;                                \
  2069.                                                   \
  2070.       for (b = 0; b < alpha; b++)                                \
  2071.         dest[b] = affect[b] ?                                \
  2072.           (unsigned char) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];    \
  2073.     }*/
  2074.  
  2075. /*shortened #define alphify(src2_alpha,new_alpha) \
  2076.     if (src2_alpha != 0 && new_alpha != 0)                            \
  2077.       {                                            \
  2078.         if (src2_alpha == new_alpha){                            \
  2079.           for (b = 0; b < alpha; b++)                            \
  2080.           dest [b] = affect [b] ? src2 [b] : src1 [b];                    \
  2081.         } else {                                        \
  2082.           ratio = (float) src2_alpha / new_alpha;                        \
  2083.           compl_ratio = 1.0 - ratio;                            \
  2084.                                                   \
  2085.           for (b = 0; b < alpha; b++)                            \
  2086.             dest[b] = affect[b] ?                                \
  2087.               (unsigned char) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];\
  2088.         }                                                                                   \
  2089.       }*/
  2090.  
  2091. #define alphify(src2_alpha,new_alpha) \
  2092.     if (src2_alpha != 0 && new_alpha != 0)                            \
  2093.       {                                            \
  2094.             b = alpha; \
  2095.         if (src2_alpha == new_alpha){                            \
  2096.           do { \
  2097.           b--; dest [b] = affect [b] ? src2 [b] : src1 [b];} while (b);    \
  2098.         } else {                                        \
  2099.           ratio = (float) src2_alpha / new_alpha;                        \
  2100.           compl_ratio = 1.0 - ratio;                            \
  2101.                                                   \
  2102.               do { b--; \
  2103.             dest[b] = affect[b] ?                                \
  2104.               (unsigned char) (src2[b] * ratio + src1[b] * compl_ratio + EPSILON) : src1[b];\
  2105.                } while (b); \
  2106.         }    \
  2107.       }
  2108.  
  2109. /*special #define alphify4(src2_alpha,new_alpha) \
  2110.     if (src2_alpha != 0 && new_alpha != 0)                            \
  2111.       {                                            \
  2112.         if (src2_alpha == new_alpha){                            \
  2113.           dest [0] = affect [0] ? src2 [0] : src1 [0];                    \
  2114.           dest [1] = affect [1] ? src2 [1] : src1 [1];                    \
  2115.           dest [2] = affect [2] ? src2 [2] : src1 [2];                    \
  2116.         } else {                                        \
  2117.           ratio = (float) src2_alpha / new_alpha;                        \
  2118.           compl_ratio = 1.0 - ratio;                            \
  2119.                                                   \
  2120.           dest[0] = affect[0] ?                                \
  2121.             (unsigned char) (src2[0] * ratio + src1[0] * compl_ratio + EPSILON) : src1[0];  \
  2122.           dest[1] = affect[1] ?                                \
  2123.             (unsigned char) (src2[1] * ratio + src1[1] * compl_ratio + EPSILON) : src1[1];  \
  2124.           dest[2] = affect[2] ?                                \
  2125.             (unsigned char) (src2[2] * ratio + src1[2] * compl_ratio + EPSILON) : src1[2];  \
  2126.         }                                                                                   \
  2127.       }*/
  2128.     
  2129. void
  2130. combine_inten_a_and_inten_pixels (const unsigned char *src1,
  2131.                   const unsigned char *src2,
  2132.                   unsigned char       *dest,
  2133.                   const unsigned char *mask,
  2134.                   int                  opacity,
  2135.                   const int           *affect,
  2136.                   int                  mode_affect,  /*  how does the combination mode affect alpha?  */
  2137.                   int                  length,
  2138.                   int                  bytes)  /*  4 or 2 depending on RGBA or GRAYA  */
  2139. {
  2140.   int alpha, b;
  2141.   int src2_bytes;
  2142.   unsigned char src2_alpha;
  2143.   unsigned char new_alpha;
  2144.   const unsigned char * m;
  2145.   float ratio, compl_ratio;
  2146.   long tmp;
  2147.  
  2148.   src2_bytes = bytes - 1;
  2149.   alpha = bytes - 1;
  2150.  
  2151.   if (mask)
  2152.     {
  2153.       m = mask;
  2154.       if (opacity == OPAQUE_OPACITY) /* HAS MASK, FULL OPACITY */
  2155.     {
  2156.       while (length--)
  2157.         {
  2158.           src2_alpha = *m;
  2159.           new_alpha = src1[alpha] +
  2160.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2161.           alphify (src2_alpha, new_alpha);
  2162.           
  2163.           if (mode_affect)
  2164.         {
  2165.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2166.         }
  2167.           else
  2168.         {
  2169.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2170.             (affect[alpha] ? new_alpha : src1[alpha]);
  2171.         }
  2172.         
  2173.           m++;
  2174.           src1 += bytes;
  2175.           src2 += src2_bytes;
  2176.           dest += bytes;
  2177.         }
  2178.     }
  2179.       else /* HAS MASK, SEMI-OPACITY */
  2180.     {
  2181.       while (length--)
  2182.         {
  2183.           src2_alpha = INT_MULT(*m, opacity, tmp);
  2184.           new_alpha = src1[alpha] +
  2185.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2186.           alphify (src2_alpha, new_alpha);
  2187.           
  2188.           if (mode_affect)
  2189.         {
  2190.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2191.         }
  2192.           else
  2193.         {
  2194.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2195.             (affect[alpha] ? new_alpha : src1[alpha]);
  2196.         }
  2197.         
  2198.           m++;
  2199.           src1 += bytes;
  2200.           src2 += src2_bytes;
  2201.           dest += bytes;
  2202.         }
  2203.     }
  2204.     }
  2205.   else /* NO MASK */
  2206.     {
  2207.       while (length --)
  2208.     {
  2209.       src2_alpha = opacity;
  2210.       new_alpha = src1[alpha] +
  2211.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2212.       alphify (src2_alpha, new_alpha);
  2213.       
  2214.       if (mode_affect)
  2215.         dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2216.       else
  2217.         dest[alpha] = (src1[alpha]) ? src1[alpha] : (affect[alpha] ? new_alpha : src1[alpha]);
  2218.  
  2219.         src1 += bytes;
  2220.         src2 += src2_bytes;
  2221.         dest += bytes;
  2222.     }
  2223.     }
  2224. }
  2225.  
  2226.  
  2227. void
  2228. combine_inten_a_and_inten_a_pixels (const unsigned char *src1,
  2229.                     const unsigned char *src2,
  2230.                     unsigned char       *dest,
  2231.                     const unsigned char *mask,
  2232.                     int                 opacity,
  2233.                     const int          *affect,
  2234.                     int                 mode_affect,  /*  how does the combination mode affect alpha?  */
  2235.                     int                 length,
  2236.                     int                 bytes)  /*  4 or 2 depending on RGBA or GRAYA  */
  2237. {
  2238.   int b;
  2239.   unsigned char src2_alpha;
  2240.   unsigned char new_alpha;
  2241.   const unsigned char * m;
  2242.   float ratio, compl_ratio;
  2243.   long tmp;
  2244.   const int alpha = bytes - 1;
  2245.  
  2246.   if (mask)
  2247.     {
  2248.       m = mask;
  2249.  
  2250.       if (opacity == OPAQUE_OPACITY) /* HAS MASK, FULL OPACITY */
  2251.     {
  2252.       const int* mask_ip;
  2253.       int i,j;
  2254.  
  2255.       if (length >= sizeof(int))
  2256.         {
  2257.           /* HEAD */
  2258.           i =  (GPOINTER_TO_INT(m) & (sizeof(int)-1));
  2259.           if (i != 0)
  2260.         {
  2261.           i = sizeof(int) - i;
  2262.           length -= i;
  2263.           while (i--)
  2264.             {
  2265.               /* GUTS */
  2266.               src2_alpha = INT_MULT(src2[alpha], *m, tmp);
  2267.               new_alpha = src1[alpha] +
  2268.             INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2269.           
  2270.               alphify (src2_alpha, new_alpha);
  2271.           
  2272.               if (mode_affect)
  2273.             {
  2274.               dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2275.             }
  2276.               else
  2277.             {
  2278.               dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2279.                 (affect[alpha] ? new_alpha : src1[alpha]);      
  2280.             }
  2281.           
  2282.               m++;
  2283.               src1 += bytes;
  2284.               src2 += bytes;
  2285.               dest += bytes;    
  2286.               /* GUTS END */
  2287.             }
  2288.         }
  2289.  
  2290.           /* BODY */
  2291.           mask_ip = (int*)m;
  2292.           i = length / sizeof(int);
  2293.           length %= sizeof(int);
  2294.           while (i--)
  2295.         {
  2296.           if (*mask_ip)
  2297.             {
  2298.               m = (const unsigned char*)mask_ip;
  2299.               j = sizeof(int);
  2300.               while (j--)
  2301.             {
  2302.               /* GUTS */
  2303.               src2_alpha = INT_MULT(src2[alpha], *m, tmp);
  2304.               new_alpha = src1[alpha] +
  2305.                 INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2306.           
  2307.               alphify (src2_alpha, new_alpha);
  2308.           
  2309.               if (mode_affect)
  2310.                 {
  2311.                   dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2312.                 }
  2313.               else
  2314.                 {
  2315.                   dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2316.                 (affect[alpha] ? new_alpha : src1[alpha]);      
  2317.                 }
  2318.           
  2319.               m++;
  2320.               src1 += bytes;
  2321.               src2 += bytes;
  2322.               dest += bytes;    
  2323.               /* GUTS END */
  2324.             }
  2325.             }
  2326.           else
  2327.             {
  2328.               j = bytes * sizeof(int);
  2329.               src2 += j;
  2330.               while (j--)
  2331.             {
  2332.               *(dest++) = *(src1++);
  2333.             }
  2334.             }
  2335.           mask_ip++;
  2336.         }
  2337.  
  2338.           m = (const unsigned char*)mask_ip;
  2339.         }
  2340.  
  2341.       /* TAIL */
  2342.       while (length--)
  2343.         {
  2344.           /* GUTS */
  2345.           src2_alpha = INT_MULT(src2[alpha], *m, tmp);
  2346.           new_alpha = src1[alpha] +
  2347.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2348.           
  2349.           alphify (src2_alpha, new_alpha);
  2350.           
  2351.           if (mode_affect)
  2352.         {
  2353.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2354.         }
  2355.           else
  2356.         {
  2357.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2358.             (affect[alpha] ? new_alpha : src1[alpha]);      
  2359.         }
  2360.           
  2361.           m++;
  2362.           src1 += bytes;
  2363.           src2 += bytes;
  2364.           dest += bytes;    
  2365.           /* GUTS END */
  2366.         }
  2367.     }
  2368.       else /* HAS MASK, SEMI-OPACITY */
  2369.     {
  2370.       const int* mask_ip;
  2371.       int i,j;
  2372.  
  2373.       if (length >= sizeof(int))
  2374.         {
  2375.           /* HEAD */
  2376.           i = (GPOINTER_TO_INT(m) & (sizeof(int)-1));
  2377.           if (i != 0)
  2378.         {
  2379.           i = sizeof(int) - i;
  2380.           length -= i;
  2381.           while (i--)
  2382.             {
  2383.               /* GUTS */
  2384.               src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2385.               new_alpha = src1[alpha] +
  2386.             INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2387.           
  2388.               alphify (src2_alpha, new_alpha);
  2389.           
  2390.               if (mode_affect)
  2391.             {
  2392.               dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2393.             }
  2394.               else
  2395.             {
  2396.               dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2397.                 (affect[alpha] ? new_alpha : src1[alpha]);
  2398.             }
  2399.           
  2400.               m++;
  2401.               src1 += bytes;
  2402.               src2 += bytes;
  2403.               dest += bytes;
  2404.               /* GUTS END */
  2405.             }
  2406.         }
  2407.       
  2408.           /* BODY */
  2409.           mask_ip = (int*)m;
  2410.           i = length / sizeof(int);
  2411.           length %= sizeof(int);
  2412.           while (i--)
  2413.         {
  2414.           if (*mask_ip)
  2415.             {
  2416.               m = (const unsigned char*)mask_ip;
  2417.               j = sizeof(int);
  2418.               while (j--)
  2419.             {
  2420.               /* GUTS */
  2421.               src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2422.               new_alpha = src1[alpha] +
  2423.                 INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2424.               
  2425.               alphify (src2_alpha, new_alpha);
  2426.               
  2427.               if (mode_affect)
  2428.                 {
  2429.                   dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2430.                 }
  2431.               else
  2432.                 {
  2433.                   dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2434.                 (affect[alpha] ? new_alpha : src1[alpha]);
  2435.                 }
  2436.  
  2437.               m++;
  2438.               src1 += bytes;
  2439.               src2 += bytes;
  2440.               dest += bytes;
  2441.               /* GUTS END */
  2442.             }
  2443.             }
  2444.           else
  2445.             {
  2446.               j = bytes * sizeof(int);
  2447.               src2 += j;
  2448.               while (j--)
  2449.             {
  2450.               *(dest++) = *(src1++);
  2451.             }
  2452.             }
  2453.           mask_ip++;
  2454.         }
  2455.  
  2456.           m = (const unsigned char*)mask_ip;
  2457.         }
  2458.     
  2459.       /* TAIL */
  2460.       while (length--)
  2461.         {
  2462.           /* GUTS */
  2463.           src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2464.           new_alpha = src1[alpha] +
  2465.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2466.           
  2467.           alphify (src2_alpha, new_alpha);
  2468.           
  2469.           if (mode_affect)
  2470.         {
  2471.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2472.         }
  2473.           else
  2474.         {
  2475.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2476.             (affect[alpha] ? new_alpha : src1[alpha]);
  2477.         }
  2478.           
  2479.           m++;
  2480.           src1 += bytes;
  2481.           src2 += bytes;
  2482.           dest += bytes;
  2483.           /* GUTS END */
  2484.         }
  2485.     }
  2486.     }
  2487.   else
  2488.     {
  2489.       if (opacity == OPAQUE_OPACITY) /* NO MASK, FULL OPACITY */
  2490.     {
  2491.       while (length --)
  2492.         {
  2493.           src2_alpha = src2[alpha];
  2494.           new_alpha = src1[alpha] +
  2495.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2496.           
  2497.           alphify (src2_alpha, new_alpha);
  2498.           
  2499.           if (mode_affect)
  2500.         {
  2501.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2502.         }
  2503.           else
  2504.         {
  2505.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2506.             (affect[alpha] ? new_alpha : src1[alpha]);
  2507.         }
  2508.         
  2509.           src1 += bytes;
  2510.           src2 += bytes;
  2511.           dest += bytes;
  2512.         }
  2513.     }
  2514.       else /* NO MASK, SEMI OPACITY */
  2515.     {
  2516.       while (length --)
  2517.         {
  2518.           src2_alpha = INT_MULT(src2[alpha], opacity, tmp);
  2519.           new_alpha = src1[alpha] +
  2520.         INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2521.           
  2522.           alphify (src2_alpha, new_alpha);
  2523.           
  2524.           if (mode_affect)
  2525.         {
  2526.           dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2527.         }
  2528.           else
  2529.         {
  2530.           dest[alpha] = (src1[alpha]) ? src1[alpha] :
  2531.             (affect[alpha] ? new_alpha : src1[alpha]);
  2532.         }
  2533.         
  2534.           src1 += bytes;
  2535.           src2 += bytes;
  2536.           dest += bytes;      
  2537.         }
  2538.     }
  2539.     }
  2540. }
  2541. #undef alphify
  2542.  
  2543. void
  2544. combine_inten_a_and_channel_mask_pixels (const unsigned char *src,
  2545.                      const unsigned char *channel,
  2546.                      unsigned char       *dest,
  2547.                      const unsigned char *col,
  2548.                      int                  opacity,
  2549.                      int                  length,
  2550.                      int                  bytes)
  2551. {
  2552.   int alpha, b;
  2553.   unsigned char channel_alpha;
  2554.   unsigned char new_alpha;
  2555.   unsigned char compl_alpha;
  2556.   int t, s;
  2557.  
  2558.   alpha = bytes - 1;
  2559.   while (length --)
  2560.     {
  2561.       channel_alpha = INT_MULT (255 - *channel, opacity, t);
  2562.       if (channel_alpha)
  2563.     {
  2564.       new_alpha = src[alpha] + INT_MULT ((255 - src[alpha]), channel_alpha, t);
  2565.  
  2566.       if (new_alpha != 255)
  2567.         channel_alpha = (channel_alpha * 255) / new_alpha;
  2568.       compl_alpha = 255 - channel_alpha;
  2569.  
  2570.       for (b = 0; b < alpha; b++)
  2571.         dest[b] = INT_MULT (col[b], channel_alpha, t) +
  2572.           INT_MULT (src[b], compl_alpha, s);
  2573.       dest[b] = new_alpha;
  2574.     }
  2575.       else
  2576.     memcpy(dest, src, bytes);
  2577.  
  2578.       /*  advance pointers  */
  2579.       src+=bytes;
  2580.       dest+=bytes;
  2581.       channel++;
  2582.     }
  2583. }
  2584.  
  2585.  
  2586. void
  2587. combine_inten_a_and_channel_selection_pixels (const unsigned char *src,
  2588.                           const unsigned char *channel,
  2589.                           unsigned char       *dest,
  2590.                           const unsigned char *col,
  2591.                           int                  opacity,
  2592.                           int                  length,
  2593.                           int                  bytes)
  2594. {
  2595.   int alpha, b;
  2596.   unsigned char channel_alpha;
  2597.   unsigned char new_alpha;
  2598.   unsigned char compl_alpha;
  2599.   int t, s;
  2600.  
  2601.   alpha = bytes - 1;
  2602.   while (length --)
  2603.     {
  2604.       channel_alpha = INT_MULT (*channel, opacity, t);
  2605.       if (channel_alpha)
  2606.     {
  2607.       new_alpha = src[alpha] + INT_MULT ((255 - src[alpha]), channel_alpha, t);
  2608.  
  2609.       if (new_alpha != 255)
  2610.         channel_alpha = (channel_alpha * 255) / new_alpha;
  2611.       compl_alpha = 255 - channel_alpha;
  2612.  
  2613.       for (b = 0; b < alpha; b++)
  2614.         dest[b] = INT_MULT (col[b], channel_alpha, t) +
  2615.           INT_MULT (src[b], compl_alpha, s);
  2616.       dest[b] = new_alpha;
  2617.     }
  2618.       else
  2619.     memcpy(dest, src, bytes);
  2620.  
  2621.       /*  advance pointers  */
  2622.       src+=bytes;
  2623.       dest+=bytes;
  2624.       channel++;
  2625.     }
  2626. }
  2627.  
  2628.  
  2629. void
  2630. behind_inten_pixels (const unsigned char *src1,
  2631.              const unsigned char *src2,
  2632.              unsigned char       *dest,
  2633.              const unsigned char *mask,
  2634.              int                  opacity,
  2635.              const int           *affect,
  2636.              int                  length,
  2637.              int                  bytes1,
  2638.              int                  bytes2,
  2639.              int                  has_alpha1,
  2640.              int                  has_alpha2)
  2641. {
  2642.   int alpha, b;
  2643.   unsigned char src1_alpha;
  2644.   unsigned char src2_alpha;
  2645.   unsigned char new_alpha;
  2646.   const unsigned char * m;
  2647.   float ratio, compl_ratio;
  2648.   long tmp;
  2649.   if (mask)
  2650.     m = mask;
  2651.   else
  2652.     m = &no_mask;
  2653.  
  2654.   /*  the alpha channel  */
  2655.   alpha = bytes1 - 1;
  2656.  
  2657.   while (length --)
  2658.     {
  2659.       src1_alpha = src1[alpha];
  2660.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2661.       new_alpha = src2_alpha +
  2662.     INT_MULT((255 - src2_alpha), src1_alpha, tmp);
  2663.       if (new_alpha)
  2664.     ratio = (float) src1_alpha / new_alpha;
  2665.       else
  2666.     ratio = 0.0;
  2667.       compl_ratio = 1.0 - ratio;
  2668.  
  2669.       for (b = 0; b < alpha; b++)
  2670.     dest[b] = (affect[b]) ?
  2671.       (unsigned char) (src1[b] * ratio + src2[b] * compl_ratio + EPSILON) :
  2672.     src1[b];
  2673.  
  2674.       dest[alpha] = (affect[alpha]) ? new_alpha : src1[alpha];
  2675.  
  2676.       if (mask)
  2677.     m++;
  2678.  
  2679.       src1 += bytes1;
  2680.       src2 += bytes2;
  2681.       dest += bytes1;
  2682.     }
  2683. }
  2684.  
  2685.  
  2686. void
  2687. behind_indexed_pixels (const unsigned char *src1,
  2688.                const unsigned char *src2,
  2689.                unsigned char       *dest,
  2690.                const unsigned char *mask,
  2691.                int                  opacity,
  2692.                const int           *affect,
  2693.                int                  length,
  2694.                int                  bytes1,
  2695.                int                  bytes2,
  2696.                int                  has_alpha1,
  2697.                int                  has_alpha2)
  2698. {
  2699.   int alpha, b;
  2700.   unsigned char src1_alpha;
  2701.   unsigned char src2_alpha;
  2702.   unsigned char new_alpha;
  2703.   const unsigned char * m;
  2704.   long tmp;
  2705.  
  2706.   if (mask)
  2707.     m = mask;
  2708.   else
  2709.     m = &no_mask;
  2710.  
  2711.   /*  the alpha channel  */
  2712.   alpha = bytes1 - 1;
  2713.  
  2714.   while (length --)
  2715.     {
  2716.       src1_alpha = src1[alpha];
  2717.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2718.       new_alpha = (src2_alpha > 127) ? OPAQUE_OPACITY : TRANSPARENT_OPACITY;
  2719.  
  2720.       for (b = 0; b < bytes1; b++)
  2721.     dest[b] = (affect[b] && new_alpha == OPAQUE_OPACITY && (src1_alpha > 127)) ?
  2722.       src2[b] : src1[b];
  2723.  
  2724.       if (mask)
  2725.     m++;
  2726.  
  2727.       src1 += bytes1;
  2728.       src2 += bytes2;
  2729.       dest += bytes1;
  2730.     }
  2731. }
  2732.  
  2733.  
  2734. void
  2735. replace_inten_pixels (const unsigned char *src1,
  2736.               const unsigned char *src2,
  2737.               unsigned char       *dest,
  2738.               const unsigned char *mask,
  2739.               int                  opacity,
  2740.               const int           *affect,
  2741.               int                  length,
  2742.               int                  bytes1,
  2743.               int                  bytes2,
  2744.               int                  has_alpha1,
  2745.               int                  has_alpha2)
  2746. {
  2747.   int b;
  2748.   int tmp;
  2749.   const int bytes = MIN (bytes1, bytes2);
  2750.  
  2751.   if (mask)
  2752.     {
  2753.       unsigned char mask_alpha;
  2754.       const unsigned char *m = mask;
  2755.       while (length --)
  2756.         {
  2757.       mask_alpha = INT_MULT(*m, opacity, tmp);
  2758.       
  2759.       for (b = 0; b < bytes; b++)
  2760.         dest[b] = (affect[b]) ?
  2761.           INT_BLEND(src2[b], src1[b], mask_alpha, tmp) :
  2762.           src1[b];
  2763.  
  2764.       if (has_alpha1 && !has_alpha2)
  2765.         dest[b] = src1[b];
  2766.  
  2767.       m++;
  2768.  
  2769.       src1 += bytes1;
  2770.       src2 += bytes2;
  2771.       dest += bytes1;
  2772.     }
  2773.     }
  2774.   else
  2775.     {
  2776.       static const unsigned char mask_alpha = OPAQUE_OPACITY ;
  2777.  
  2778.       while (length --)
  2779.         {
  2780.       for (b = 0; b < bytes; b++)
  2781.         dest[b] = (affect[b]) ?
  2782.           INT_BLEND(src2[b], src1[b], mask_alpha, tmp) :
  2783.           src1[b];
  2784.  
  2785.       if (has_alpha1 && !has_alpha2)
  2786.         dest[b] = src1[b];
  2787.  
  2788.       src1 += bytes1;
  2789.       src2 += bytes2;
  2790.       dest += bytes1;
  2791.     }
  2792.     }
  2793. }
  2794.  
  2795.  
  2796. void
  2797. replace_indexed_pixels (const unsigned char *src1,
  2798.             const unsigned char *src2,
  2799.             unsigned char       *dest,
  2800.             const unsigned char *mask,
  2801.             int                  opacity,
  2802.             const int           *affect,
  2803.             int                  length,
  2804.             int                  bytes1,
  2805.             int                  bytes2,
  2806.             int                  has_alpha1,
  2807.             int                  has_alpha2)
  2808. {
  2809.   int bytes, b;
  2810.   unsigned char mask_alpha;
  2811.   const unsigned char * m;
  2812.   int tmp;
  2813.   if (mask)
  2814.     m = mask;
  2815.   else
  2816.     m = &no_mask;
  2817.  
  2818.   bytes = MIN (bytes1, bytes2);
  2819.   while (length --)
  2820.     {
  2821.       mask_alpha = INT_MULT(*m, opacity, tmp);
  2822.  
  2823.       for (b = 0; b < bytes; b++)
  2824.     dest[b] = (affect[b] && mask_alpha) ?
  2825.       src2[b] : src1[b];
  2826.  
  2827.       if (has_alpha1 && !has_alpha2)
  2828.     dest[b] = src1[b];
  2829.  
  2830.       if (mask)
  2831.     m++;
  2832.  
  2833.       src1 += bytes1;
  2834.       src2 += bytes2;
  2835.       dest += bytes1;
  2836.     }
  2837. }
  2838.  
  2839.  
  2840. void
  2841. erase_inten_pixels (const unsigned char *src1,
  2842.             const unsigned char *src2,
  2843.             unsigned char       *dest,
  2844.             const unsigned char *mask,
  2845.             int                  opacity,
  2846.             const int           *affect,
  2847.             int                  length,
  2848.             int                  bytes)
  2849. {
  2850.   int b;
  2851.   unsigned char src2_alpha;
  2852.   long tmp;
  2853.   const int alpha = bytes - 1;
  2854.  
  2855.   if (mask)
  2856.     {
  2857.       const unsigned char *m = mask;
  2858.  
  2859.       while (length --)
  2860.         {
  2861.       for (b = 0; b < alpha; b++)
  2862.         dest[b] = src1[b];
  2863.  
  2864.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2865.       dest[alpha] = src1[alpha] - INT_MULT(src1[alpha], src2_alpha, tmp);
  2866.  
  2867.       m++;
  2868.  
  2869.       src1 += bytes;
  2870.       src2 += bytes;
  2871.       dest += bytes;
  2872.     }
  2873.     }
  2874.   else
  2875.     {
  2876.       unsigned char *m = &no_mask;
  2877.  
  2878.       while (length --)
  2879.         {
  2880.       for (b = 0; b < alpha; b++)
  2881.         dest[b] = src1[b];
  2882.  
  2883.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2884.       dest[alpha] = src1[alpha] - INT_MULT(src1[alpha], src2_alpha, tmp);
  2885.  
  2886.       src1 += bytes;
  2887.       src2 += bytes;
  2888.       dest += bytes;
  2889.     }
  2890.     }
  2891. }
  2892.  
  2893.  
  2894. void
  2895. erase_indexed_pixels (const unsigned char *src1,
  2896.               const unsigned char *src2,
  2897.               unsigned char       *dest,
  2898.               const unsigned char *mask,
  2899.               int                  opacity,
  2900.               const int           *affect,
  2901.               int                  length,
  2902.               int                  bytes)
  2903. {
  2904.   int alpha, b;
  2905.   unsigned char src2_alpha;
  2906.   const unsigned char * m;
  2907.   long tmp;
  2908.   if (mask)
  2909.     m = mask;
  2910.   else
  2911.     m = &no_mask;
  2912.  
  2913.   alpha = bytes - 1;
  2914.   while (length --)
  2915.     {
  2916.       for (b = 0; b < alpha; b++)
  2917.     dest[b] = src1[b];
  2918.  
  2919.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2920.       dest[alpha] = (src2_alpha > 127) ? TRANSPARENT_OPACITY : src1[alpha];
  2921.  
  2922.       if (mask)
  2923.     m++;
  2924.  
  2925.       src1 += bytes;
  2926.       src2 += bytes;
  2927.       dest += bytes;
  2928.     }
  2929. }
  2930.  
  2931. void
  2932. anti_erase_inten_pixels (const unsigned char *src1,
  2933.              const unsigned char *src2,
  2934.              unsigned char       *dest,
  2935.              const unsigned char *mask,
  2936.              int                  opacity,
  2937.              const int           *affect,
  2938.              int                  length,
  2939.              int                  bytes)
  2940. {
  2941.   int alpha, b;
  2942.   unsigned char src2_alpha;
  2943.   const unsigned char * m;
  2944.   long tmp;
  2945.  
  2946.   if (mask)
  2947.     m = mask;
  2948.   else
  2949.     m = &no_mask;
  2950.  
  2951.   alpha = bytes - 1;
  2952.   while (length --)
  2953.     {
  2954.       for (b = 0; b < alpha; b++)
  2955.     dest[b] = src1[b];
  2956.  
  2957.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2958.       dest[alpha] = src1[alpha] + INT_MULT((255 - src1[alpha]), src2_alpha, tmp);
  2959.  
  2960.       if (mask)
  2961.     m++;
  2962.  
  2963.       src1 += bytes;
  2964.       src2 += bytes;
  2965.       dest += bytes;
  2966.     }
  2967. }
  2968.  
  2969. void
  2970. anti_erase_indexed_pixels (const unsigned char *src1,
  2971.                const unsigned char *src2,
  2972.                unsigned char       *dest,
  2973.                const unsigned char *mask,
  2974.                int                  opacity,
  2975.                const int           *affect,
  2976.                int                  length,
  2977.                int                  bytes)
  2978. {
  2979.   int alpha, b;
  2980.   unsigned char src2_alpha;
  2981.   const unsigned char * m;
  2982.   long tmp;
  2983.   if (mask)
  2984.     m = mask;
  2985.   else
  2986.     m = &no_mask;
  2987.  
  2988.   alpha = bytes - 1;
  2989.   while (length --)
  2990.     {
  2991.       for (b = 0; b < alpha; b++)
  2992.     dest[b] = src1[b];
  2993.  
  2994.       src2_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp);
  2995.       dest[alpha] = (src2_alpha > 127) ? OPAQUE_OPACITY : src1[alpha];
  2996.  
  2997.       if (mask)
  2998.     m++;
  2999.  
  3000.       src1 += bytes;
  3001.       src2 += bytes;
  3002.       dest += bytes;
  3003.     }
  3004. }
  3005.  
  3006.  
  3007. void
  3008. extract_from_inten_pixels (unsigned char *src,
  3009.                unsigned char       *dest,
  3010.                const unsigned char *mask,
  3011.                const unsigned char *bg,
  3012.                int                  cut,
  3013.                int                  length,
  3014.                int                  bytes,
  3015.                int                  has_alpha)
  3016. {
  3017.   int b, alpha;
  3018.   int dest_bytes;
  3019.   const unsigned char * m;
  3020.   int tmp;
  3021.   if (mask)
  3022.     m = mask;
  3023.   else
  3024.     m = &no_mask;
  3025.  
  3026.   alpha = (has_alpha) ? bytes - 1 : bytes;
  3027.   dest_bytes = (has_alpha) ? bytes : bytes + 1;
  3028.   while (length --)
  3029.     {
  3030.       for (b = 0; b < alpha; b++)
  3031.     dest[b] = src[b];
  3032.  
  3033.       if (has_alpha)
  3034.     {
  3035.       dest[alpha] = INT_MULT(*m, src[alpha], tmp);
  3036.       if (cut)
  3037.         src[alpha] = INT_MULT((255 - *m), src[alpha], tmp);
  3038.     }
  3039.       else
  3040.     {
  3041.       dest[alpha] = *m;
  3042.       if (cut)
  3043.         for (b = 0; b < bytes; b++)
  3044.           src[b] = INT_BLEND(bg[b], src[b], *m, tmp);
  3045.     }
  3046.  
  3047.       if (mask)
  3048.     m++;
  3049.  
  3050.       src += bytes;
  3051.       dest += dest_bytes;
  3052.     }
  3053. }
  3054.  
  3055.  
  3056. void
  3057. extract_from_indexed_pixels (unsigned char       *src,
  3058.                  unsigned char       *dest,
  3059.                  const unsigned char *mask,
  3060.                  const unsigned char *cmap,
  3061.                  const unsigned char *bg,
  3062.                  int                  cut,
  3063.                  int                  length,
  3064.                  int                  bytes,
  3065.                  int                  has_alpha)
  3066. {
  3067.   int b;
  3068.   int index;
  3069.   const unsigned char * m;
  3070.   int t;
  3071.  
  3072.   if (mask)
  3073.     m = mask;
  3074.   else
  3075.     m = &no_mask;
  3076.  
  3077.   while (length --)
  3078.     {
  3079.       index = src[0] * 3;
  3080.       for (b = 0; b < 3; b++)
  3081.     dest[b] = cmap[index + b];
  3082.  
  3083.       if (has_alpha)
  3084.     {
  3085.       dest[3] = INT_MULT (*m, src[1], t);
  3086.       if (cut)
  3087.         src[1] = INT_MULT ((255 - *m), src[1], t);
  3088.     }
  3089.       else
  3090.     {
  3091.       dest[3] = *m;
  3092.       if (cut)
  3093.         src[0] = (*m > 127) ? bg[0] : src[0];
  3094.     }
  3095.  
  3096.       if (mask)
  3097.     m++;
  3098.  
  3099.       src += bytes;
  3100.       dest += 4;
  3101.     }
  3102. }
  3103.  
  3104.  
  3105. void
  3106. map_to_color (int                  src_type,
  3107.           const unsigned char *cmap,
  3108.           const unsigned char *src,
  3109.           unsigned char       *rgb)
  3110. {
  3111.   switch (src_type)
  3112.     {
  3113.     case 0:  /*  RGB      */
  3114.       /*  Straight copy  */
  3115.       *rgb++ = *src++;
  3116.       *rgb++ = *src++;
  3117.       *rgb   = *src;
  3118.       break;
  3119.     case 1:  /*  GRAY     */
  3120.       *rgb++ = *src;
  3121.       *rgb++ = *src;
  3122.       *rgb   = *src;
  3123.       break;
  3124.     case 2:  /*  INDEXED  */
  3125.       {
  3126.     int index = *src * 3;
  3127.     *rgb++ = cmap [index++];
  3128.     *rgb++ = cmap [index++];
  3129.     *rgb   = cmap [index++];
  3130.       }
  3131.       break;
  3132.     }
  3133. }
  3134.  
  3135.  
  3136. int
  3137. map_rgb_to_indexed (const unsigned char *cmap,
  3138.             int             num_cols,
  3139.             const GimpImage*     gimage,
  3140.             int             r,
  3141.             int             g,
  3142.             int             b)
  3143. {
  3144.   unsigned int pixel;
  3145.   int hash_index;
  3146.   int cmap_index;
  3147.  
  3148.   pixel = (r << 16) | (g << 8) | b;
  3149.   hash_index = pixel % HASH_TABLE_SIZE;
  3150.  
  3151.   /*  Hash table lookup hit  */
  3152.   if (color_hash_table[hash_index].gimage == gimage &&
  3153.       color_hash_table[hash_index].pixel == pixel)
  3154.     {
  3155.       cmap_index = color_hash_table[hash_index].index;
  3156.       color_hash_hits++;
  3157.     }
  3158.   /*  Hash table lookup miss  */
  3159.   else
  3160.     {
  3161.       const unsigned char *col;
  3162.       int diff, sum, max;
  3163.       int i;
  3164.  
  3165.       max = MAXDIFF;
  3166.       cmap_index = 0;
  3167.  
  3168.       col = cmap;
  3169.       for (i = 0; i < num_cols; i++)
  3170.     {
  3171.       diff = r - *col++;
  3172.       sum = diff * diff;
  3173.       diff = g - *col++;
  3174.       sum += diff * diff;
  3175.       diff = b - *col++;
  3176.       sum += diff * diff;
  3177.  
  3178.       if (sum < max)
  3179.         {
  3180.           cmap_index = i;
  3181.           max = sum;
  3182.         }
  3183.     }
  3184.  
  3185.       /*  update the hash table  */
  3186.       color_hash_table[hash_index].pixel = pixel;
  3187.       color_hash_table[hash_index].index = cmap_index;
  3188.       color_hash_table[hash_index].gimage = gimage;
  3189.       color_hash_misses++;
  3190.     }
  3191.  
  3192.   return cmap_index;
  3193. }
  3194.  
  3195.  
  3196.  
  3197. /**************************************************/
  3198. /*    REGION FUNCTIONS                            */
  3199. /**************************************************/
  3200.  
  3201. void
  3202. color_region (PixelRegion   *dest,
  3203.           const unsigned char *col)
  3204. {
  3205.   int h;
  3206.   unsigned char * s;
  3207.   void * pr;
  3208.  
  3209.   for (pr = pixel_regions_register (1, dest); pr != NULL; pr = pixel_regions_process (pr))
  3210.     {
  3211.       h = dest->h;
  3212.       s = dest->data;
  3213.  
  3214.       if (dest->w*dest->bytes == dest->rowstride)
  3215.       {
  3216.     /* do it all in one function call if we can */
  3217.     /* this hasn't been tested to see if it is a
  3218.        signifigant speed gain yet */
  3219.     color_pixels (s, col, dest->w*h, dest->bytes);
  3220.       }
  3221.       else
  3222.       {
  3223.     while (h--)
  3224.     {
  3225.       color_pixels (s, col, dest->w, dest->bytes);
  3226.       s += dest->rowstride;
  3227.     }
  3228.       }
  3229.     }
  3230. }
  3231.  
  3232.  
  3233. void
  3234. blend_region (PixelRegion *src1,
  3235.           PixelRegion *src2,
  3236.           PixelRegion *dest,
  3237.           int          blend)
  3238. {
  3239.   int h;
  3240.   unsigned char *s1, *s2, * d;
  3241.   void * pr;
  3242.  
  3243.   for (pr = pixel_regions_register (3, src1, src2, dest); pr != NULL; pr = pixel_regions_process (pr))
  3244.     {
  3245.       s1 = src1->data;
  3246.       s2 = src2->data;
  3247.       d = dest->data;
  3248.       h = src1->h;
  3249.  
  3250.       while (h --)
  3251.     {
  3252.           blend_pixels (s1, s2, d, blend, src1->w, src1->bytes, FALSE);
  3253.       s1 += src1->rowstride;
  3254.       s2 += src2->rowstride;
  3255.       d += dest->rowstride;
  3256.     }
  3257.     }
  3258. }
  3259.  
  3260.  
  3261. void
  3262. shade_region (PixelRegion   *src,
  3263.           PixelRegion   *dest,
  3264.           unsigned char *col,
  3265.           int            blend)
  3266. {
  3267.   int h;
  3268.   unsigned char * s, * d;
  3269.  
  3270.   s = src->data;
  3271.   d = dest->data;
  3272.   h = src->h;
  3273.  
  3274.   while (h --)
  3275.     {
  3276. /*      blend_pixels (s, d, col, blend, src->w, src->bytes);*/
  3277.       s += src->rowstride;
  3278.       d += dest->rowstride;
  3279.     }
  3280. }
  3281.  
  3282.  
  3283.  
  3284. void
  3285. copy_region (PixelRegion *src,
  3286.          PixelRegion *dest)
  3287. {
  3288.   int h;
  3289.   int pixelwidth;
  3290.   unsigned char * s, * d;
  3291.   void * pr;
  3292.  
  3293. #ifdef COWSHOW
  3294.   fputc('[',stderr);
  3295. #endif
  3296.   for (pr = pixel_regions_register (2, src, dest);
  3297.        pr != NULL;
  3298.        pr = pixel_regions_process (pr))
  3299.     {
  3300.       if (src->tiles && dest->tiles &&
  3301.       src->curtile && dest->curtile &&
  3302.       src->offx == 0 && dest->offx == 0 &&
  3303.       src->offy == 0 && dest->offy == 0 &&
  3304.       src->w == (src->curtile->ewidth) && 
  3305.       dest->w == (dest->curtile->ewidth) &&
  3306.       src->h == tile_eheight(src->curtile) && 
  3307.       dest->h == tile_eheight(dest->curtile)) 
  3308.     {
  3309. #ifdef COWSHOW
  3310.       fputc('!',stderr);
  3311. #endif
  3312.       tile_manager_map_over_tile (dest->tiles, dest->curtile, src->curtile);
  3313.     }
  3314.       else 
  3315.     {
  3316. #ifdef COWSHOW
  3317.       fputc('.',stderr);
  3318. #endif
  3319.       pixelwidth = src->w * src->bytes;
  3320.       s = src->data;
  3321.       d = dest->data;
  3322.       h = src->h;
  3323.       
  3324.       while (h --)
  3325.         {
  3326.           memcpy (d, s, pixelwidth);
  3327.           s += src->rowstride;
  3328.           d += dest->rowstride;
  3329.         }
  3330.     }
  3331.     }
  3332. #ifdef COWSHOW
  3333.   fputc(']',stderr);
  3334.   fputc('\n',stderr);
  3335. #endif
  3336. }
  3337.  
  3338.  
  3339. void
  3340. add_alpha_region (PixelRegion *src,
  3341.           PixelRegion *dest)
  3342. {
  3343.   int h;
  3344.   unsigned char * s, * d;
  3345.   void * pr;
  3346.  
  3347.   for (pr = pixel_regions_register (2, src, dest); pr != NULL; pr = pixel_regions_process (pr))
  3348.     {
  3349.       s = src->data;
  3350.       d = dest->data;
  3351.       h = src->h;
  3352.  
  3353.       while (h --)
  3354.     {
  3355.       add_alpha_pixels (s, d, src->w, src->bytes);
  3356.       s += src->rowstride;
  3357.       d += dest->rowstride;
  3358.     }
  3359.     }
  3360. }
  3361.  
  3362.  
  3363. void
  3364. flatten_region (PixelRegion   *src,
  3365.         PixelRegion   *dest,
  3366.         unsigned char *bg)
  3367. {
  3368.   int h;
  3369.   unsigned char * s, * d;
  3370.  
  3371.   s = src->data;
  3372.   d = dest->data;
  3373.   h = src->h;
  3374.  
  3375.   while (h --)
  3376.     {
  3377.       flatten_pixels (s, d, bg, src->w, src->bytes);
  3378.       s += src->rowstride;
  3379.       d += dest->rowstride;
  3380.     }
  3381. }
  3382.  
  3383.  
  3384. void
  3385. extract_alpha_region (PixelRegion *src,
  3386.               PixelRegion *mask,
  3387.               PixelRegion *dest)
  3388. {
  3389.   int h;
  3390.   unsigned char * s, * m, * d;
  3391.   void * pr;
  3392.  
  3393.   for (pr = pixel_regions_register (3, src, mask, dest); pr != NULL; pr = pixel_regions_process (pr))
  3394.     {
  3395.       s = src->data;
  3396.       d = dest->data;
  3397.       if (mask)
  3398.     m = mask->data;
  3399.       else
  3400.     m = NULL;
  3401.  
  3402.       h = src->h;
  3403.       while (h --)
  3404.     {
  3405.       extract_alpha_pixels (s, m, d, src->w, src->bytes);
  3406.       s += src->rowstride;
  3407.       d += dest->rowstride;
  3408.       if (mask)
  3409.         m += mask->rowstride;
  3410.     }
  3411.     }
  3412. }
  3413.  
  3414.  
  3415. void
  3416. extract_from_region (PixelRegion   *src,
  3417.              PixelRegion   *dest,
  3418.              PixelRegion   *mask,
  3419.              unsigned char *cmap,
  3420.              unsigned char *bg,
  3421.              int            type,
  3422.              int            has_alpha,
  3423.              int            cut)
  3424. {
  3425.   int h;
  3426.   unsigned char * s, * d, * m;
  3427.   void * pr;
  3428.  
  3429.   for (pr = pixel_regions_register (3, src, dest, mask); pr != NULL; pr = pixel_regions_process (pr))
  3430.     {
  3431.       s = src->data;
  3432.       d = dest->data;
  3433.       m = (mask) ? mask->data : NULL;
  3434.       h = src->h;
  3435.  
  3436.       while (h --)
  3437.     {
  3438.       switch (type)
  3439.         {
  3440.         case 0:  /*  RGB      */
  3441.         case 1:  /*  GRAY     */
  3442.           extract_from_inten_pixels (s, d, m, bg, cut, src->w,
  3443.                      src->bytes, has_alpha);
  3444.           break;
  3445.         case 2:  /*  INDEXED  */
  3446.           extract_from_indexed_pixels (s, d, m, cmap, bg, cut, src->w,
  3447.                        src->bytes, has_alpha);
  3448.           break;
  3449.         }
  3450.  
  3451.       s += src->rowstride;
  3452.       d += dest->rowstride;
  3453.       if (mask)
  3454.         m += mask->rowstride;
  3455.     }
  3456.     }
  3457. }
  3458.  
  3459.  
  3460. void
  3461. convolve_region (PixelRegion    *srcR,
  3462.          PixelRegion    *destR,
  3463.          int        *matrix,
  3464.          int         size,
  3465.          int         divisor,
  3466.          ConvolutionType mode)
  3467. {
  3468.   /*  Convolve the src image using the convolution matrix, writing to dest  */
  3469.   /*  Convolve is not tile-enabled--use accordingly  */
  3470.   unsigned char *src, *s_row, * s;
  3471.   unsigned char *dest, * d;
  3472.   int * m;
  3473.   int total [4];
  3474.   int b, bytes;
  3475.   int length;
  3476.   int wraparound;
  3477.   int margin;      /*  margin imposed by size of conv. matrix  */
  3478.   int i, j;
  3479.   int x, y;
  3480.   int offset;
  3481.  
  3482.   /*  If the mode is NEGATIVE_CONVOL, the offset should be 128  */
  3483.   if (mode == NEGATIVE_CONVOL)
  3484.     {
  3485.       offset = 128;
  3486.       mode = NORMAL_CONVOL;
  3487.     }
  3488.   else
  3489.     offset = 0;
  3490.  
  3491.   /*  check for the boundary cases  */
  3492.   if (srcR->w < (size - 1) || srcR->h < (size - 1))
  3493.     return;
  3494.  
  3495.   /*  Initialize some values  */
  3496.   bytes = srcR->bytes;
  3497.   length = bytes * srcR->w;
  3498.   margin = size / 2;
  3499.   src = srcR->data;
  3500.   dest = destR->data;
  3501.  
  3502.   /*  calculate the source wraparound value  */
  3503.   wraparound = srcR->rowstride - size * bytes;
  3504.  
  3505.   /* copy the first (size / 2) scanlines of the src image... */
  3506.   for (i = 0; i < margin; i++)
  3507.     {
  3508.       memcpy (dest, src, length);
  3509.       src += srcR->rowstride;
  3510.       dest += destR->rowstride;
  3511.     }
  3512.  
  3513.   src = srcR->data;
  3514.  
  3515.   for (y = margin; y < srcR->h - margin; y++)
  3516.     {
  3517.       s_row = src;
  3518.       s = s_row + srcR->rowstride*margin;
  3519.       d = dest;
  3520.  
  3521.       /* handle the first margin pixels... */
  3522.       b = bytes * margin;
  3523.       while (b --)
  3524.     *d++ = *s++;
  3525.  
  3526.       /* now, handle the center pixels */
  3527.       x = srcR->w - margin*2;
  3528.       while (x--)
  3529.     {
  3530.       s = s_row;
  3531.  
  3532.       m = matrix;
  3533.       total [0] = total [1] = total [2] = total [3] = 0;
  3534.       i = size;
  3535.       while (i --)
  3536.         {
  3537.           j = size;
  3538.           while (j --)
  3539.         {
  3540.           for (b = 0; b < bytes; b++)
  3541.             total [b] += *m * *s++;
  3542.           m ++;
  3543.         }
  3544.  
  3545.           s += wraparound;
  3546.         }
  3547.  
  3548.       for (b = 0; b < bytes; b++)
  3549.         {
  3550.           total [b] = total [b] / divisor + offset;
  3551.  
  3552.           if (total [b] < 0 && mode != NORMAL_CONVOL)
  3553.         total [b] = - total [b];
  3554.  
  3555.           if (total [b] < 0)
  3556.         *d++ = 0;
  3557.           else
  3558.         *d++ = (total [b] > 255) ? 255 : (unsigned char) total [b];
  3559.         }
  3560.  
  3561.       s_row += bytes;
  3562.  
  3563.     }
  3564.  
  3565.       /* handle the last pixel... */
  3566.       s = s_row + (srcR->rowstride + bytes) * margin;
  3567.       b = bytes * margin;
  3568.       while (b --)
  3569.     *d++ = *s++;
  3570.  
  3571.       /* set the memory pointers */
  3572.       src += srcR->rowstride;
  3573.       dest += destR->rowstride;
  3574.     }
  3575.  
  3576.   src += srcR->rowstride*margin;
  3577.  
  3578.   /* copy the last (margin) scanlines of the src image... */
  3579.   for (i = 0; i < margin; i++)
  3580.     {
  3581.       memcpy (dest, src, length);
  3582.       src += srcR->rowstride;
  3583.       dest += destR->rowstride;
  3584.     }
  3585. }
  3586.  
  3587. /* Convert from separated alpha to premultiplied alpha. Only works on
  3588.    non-tiled regions! */
  3589. void
  3590. multiply_alpha_region (PixelRegion *srcR)
  3591. {
  3592.   unsigned char *src, *s;
  3593.   int x, y;
  3594.   int width, height;
  3595.   int b, bytes;
  3596.   double alpha_val;
  3597.  
  3598.   width = srcR->w;
  3599.   height = srcR->h;
  3600.   bytes = srcR->bytes;
  3601.  
  3602.   src = srcR->data;
  3603.  
  3604.   for (y = 0; y < height; y++)
  3605.     {
  3606.       s = src;
  3607.       for (x = 0; x < width; x++)
  3608.     {
  3609.       alpha_val = s[bytes - 1] * (1.0 / 255.0);
  3610.       for (b = 0; b < bytes - 1; b++)
  3611.         s[b] = 0.5 + s[b] * alpha_val;
  3612.       s += bytes;
  3613.     }
  3614.       src += srcR->rowstride;
  3615.     }
  3616. }
  3617.  
  3618. /* Convert from premultiplied alpha to separated alpha. Only works on
  3619.    non-tiled regions! */
  3620. void
  3621. separate_alpha_region (PixelRegion *srcR)
  3622. {
  3623.   unsigned char *src, *s;
  3624.   int x, y;
  3625.   int width, height;
  3626.   int b, bytes;
  3627.   double alpha_recip;
  3628.   int new_val;
  3629.  
  3630.   width = srcR->w;
  3631.   height = srcR->h;
  3632.   bytes = srcR->bytes;
  3633.  
  3634.   src = srcR->data;
  3635.  
  3636.   for (y = 0; y < height; y++)
  3637.     {
  3638.       s = src;
  3639.       for (x = 0; x < width; x++)
  3640.     {
  3641.       /* predicate is equivalent to:
  3642.          (((s[bytes - 1] - 1) & 255) + 2) & 256
  3643.          */
  3644.       if (s[bytes - 1] != 0 && s[bytes - 1] != 255)
  3645.         {
  3646.           alpha_recip = 255.0 / s[bytes - 1];
  3647.           for (b = 0; b < bytes - 1; b++)
  3648.         {
  3649.           new_val = 0.5 + s[b] * alpha_recip;
  3650.           new_val = MIN (new_val, 255);
  3651.           s[b] = new_val;
  3652.         }
  3653.         }
  3654.       s += bytes;
  3655.     }
  3656.       src += srcR->rowstride;
  3657.     }
  3658. }
  3659.  
  3660. void
  3661. gaussian_blur_region (PixelRegion *srcR,
  3662.               double       radius_x,
  3663.               double       radius_y)
  3664. {
  3665.   double std_dev;
  3666.   long width, height;
  3667.   int bytes;
  3668.   unsigned char *src, *sp;
  3669.   unsigned char *dest, *dp;
  3670.   unsigned char *data;
  3671.   int *buf, *b;
  3672.   int pixels;
  3673.   int total;
  3674.   int i, row, col;
  3675.   int start, end;
  3676.   int *curve;
  3677.   int *sum;
  3678.   int val;
  3679.   int length;
  3680.   int alpha;
  3681.   int initial_p, initial_m;
  3682.  
  3683.   if (radius_x == 0.0 && radius_y == 0.0) return;    /* zero blur is a no-op */
  3684.  
  3685.   /*  allocate the result buffer  */
  3686.   length = MAX (srcR->w, srcR->h) * srcR->bytes;
  3687.   data = paint_funcs_get_buffer (length * 2);
  3688.   src = data;
  3689.   dest = data + length;
  3690.  
  3691.   width = srcR->w;
  3692.   height = srcR->h;
  3693.   bytes = srcR->bytes;
  3694.   alpha = bytes - 1;
  3695.  
  3696.   buf = g_malloc (sizeof (int) * MAX (width, height) * 2);
  3697.  
  3698.   if (radius_y != 0.0)
  3699.     {
  3700.       std_dev = sqrt (-(radius_y * radius_y) / (2 * log (1.0 / 255.0)));
  3701.       curve = make_curve (std_dev, &length);
  3702.       sum = g_malloc (sizeof (int) * (2 * length + 1));
  3703.       sum[0] = 0;
  3704.  
  3705.       for (i = 1; i <= length*2; i++)
  3706.     sum[i] = curve[i-length-1] + sum[i-1];
  3707.       sum += length;
  3708.  
  3709.       total = sum[length] - sum[-length];
  3710.  
  3711.       for (col = 0; col < width; col++)
  3712.     {
  3713.       pixel_region_get_col (srcR, col + srcR->x, srcR->y, height, src, 1);
  3714.       sp = src + alpha;
  3715.  
  3716.       initial_p = sp[0];
  3717.       initial_m = sp[(height-1) * bytes];
  3718.  
  3719.       /*  Determine a run-length encoded version of the column  */
  3720.       run_length_encode (sp, buf, height, bytes);
  3721.  
  3722.       for (row = 0; row < height; row++)
  3723.         {
  3724.           start = (row < length) ? -row : -length;
  3725.           end = (height <= (row + length)) ? (height - row - 1) : length;
  3726.  
  3727.           val = 0;
  3728.           i = start;
  3729.           b = buf + (row + i) * 2;
  3730.  
  3731.           if (start != -length)
  3732.         val += initial_p * (sum[start] - sum[-length]);
  3733.  
  3734.           while (i < end)
  3735.         {
  3736.           pixels = b[0];
  3737.           i += pixels;
  3738.           if (i > end)
  3739.             i = end;
  3740.           val += b[1] * (sum[i] - sum[start]);
  3741.           b += (pixels * 2);
  3742.           start = i;
  3743.         }
  3744.  
  3745.           if (end != length)
  3746.         val += initial_m * (sum[length] - sum[end]);
  3747.  
  3748.           sp[row * bytes] = val / total;
  3749.         }
  3750.  
  3751.       pixel_region_set_col (srcR, col + srcR->x, srcR->y, height, src);
  3752.     }
  3753.  
  3754.       g_free (sum - length);
  3755.       g_free (curve - length);
  3756.     }
  3757.  
  3758.   if (radius_x != 0.0)
  3759.     {
  3760.       std_dev = sqrt (-(radius_x * radius_x) / (2 * log (1.0 / 255.0)));
  3761.       curve = make_curve (std_dev, &length);
  3762.       sum = g_malloc (sizeof (int) * (2 * length + 1));
  3763.       sum[0] = 0;
  3764.  
  3765.       for (i = 1; i <= length*2; i++)
  3766.     sum[i] = curve[i-length-1] + sum[i-1];
  3767.       sum += length;
  3768.  
  3769.       total = sum[length] - sum[-length];
  3770.  
  3771.       for (row = 0; row < height; row++)
  3772.     {
  3773.       pixel_region_get_row (srcR, srcR->x, row + srcR->y, width, src, 1);
  3774.       sp = src + alpha;
  3775.       dp = dest + alpha;
  3776.  
  3777.       initial_p = sp[0];
  3778.       initial_m = sp[(width-1) * bytes];
  3779.  
  3780.       /*  Determine a run-length encoded version of the row  */
  3781.       run_length_encode (sp, buf, width, bytes);
  3782.  
  3783.       for (col = 0; col < width; col++)
  3784.         {
  3785.           start = (col < length) ? -col : -length;
  3786.           end = (width <= (col + length)) ? (width - col - 1) : length;
  3787.  
  3788.           val = 0;
  3789.           i = start;
  3790.           b = buf + (col + i) * 2;
  3791.  
  3792.           if (start != -length)
  3793.         val += initial_p * (sum[start] - sum[-length]);
  3794.  
  3795.           while (i < end)
  3796.         {
  3797.           pixels = b[0];
  3798.           i += pixels;
  3799.           if (i > end)
  3800.             i = end;
  3801.           val += b[1] * (sum[i] - sum[start]);
  3802.           b += (pixels * 2);
  3803.           start = i;
  3804.         }
  3805.  
  3806.           if (end != length)
  3807.         val += initial_m * (sum[length] - sum[end]);
  3808.  
  3809.           val = val / total;
  3810.  
  3811.           dp[col * bytes] = val;
  3812.         }
  3813.       
  3814.       pixel_region_set_row (srcR, srcR->x, row + srcR->y, width, dest);
  3815.     }
  3816.  
  3817.       g_free (sum - length);
  3818.       g_free (curve - length);
  3819.     }
  3820.  
  3821.   g_free (buf);
  3822. }
  3823.  
  3824.  
  3825. /* non-interpolating scale_region.  [adam]
  3826.  */
  3827. void
  3828. scale_region_no_resample (PixelRegion *srcPR,
  3829.               PixelRegion *destPR)
  3830. {
  3831.   int * x_src_offsets;
  3832.   int * y_src_offsets;
  3833.   unsigned char * src;
  3834.   unsigned char * dest;
  3835.   int width, height, orig_width, orig_height;
  3836.   int last_src_y;
  3837.   int row_bytes;
  3838.   int x,y,b;
  3839.   char bytes;
  3840.  
  3841.   orig_width = srcPR->w;
  3842.   orig_height = srcPR->h;
  3843.  
  3844.   width = destPR->w;
  3845.   height = destPR->h;
  3846.  
  3847.   bytes = srcPR->bytes;
  3848.  
  3849.   /*  the data pointers...  */
  3850.   x_src_offsets = (int *) g_malloc (width * bytes * sizeof(int));
  3851.   y_src_offsets = (int *) g_malloc (height * sizeof(int));
  3852.   src  = (unsigned char *) g_malloc (orig_width * bytes);
  3853.   dest = (unsigned char *) g_malloc (width * bytes);
  3854.   
  3855.   /*  pre-calc the scale tables  */
  3856.   for (b = 0; b < bytes; b++)
  3857.     {
  3858.       for (x = 0; x < width; x++)
  3859.     {
  3860.       x_src_offsets [b + x * bytes] = b + bytes * ((x * orig_width + orig_width / 2) / width);
  3861.     }
  3862.     }
  3863.   for (y = 0; y < height; y++)
  3864.     {
  3865.       y_src_offsets [y] = (y * orig_height + orig_height / 2) / height;
  3866.     }
  3867.   
  3868.   /*  do the scaling  */
  3869.   row_bytes = width * bytes;
  3870.   last_src_y = -1;
  3871.   for (y = 0; y < height; y++)
  3872.     {
  3873.       /* if the source of this line was the same as the source
  3874.        *  of the last line, there's no point in re-rescaling.
  3875.        */
  3876.       if (y_src_offsets[y] != last_src_y)
  3877.     {
  3878.       pixel_region_get_row (srcPR, 0, y_src_offsets[y], orig_width, src, 1);
  3879.       for (x = 0; x < row_bytes ; x++)
  3880.         {
  3881.           dest[x] = src[x_src_offsets[x]];
  3882.         }
  3883.       last_src_y = y_src_offsets[y];
  3884.     }
  3885.  
  3886.       pixel_region_set_row (destPR, 0, y, width, dest);
  3887.     }
  3888.   
  3889.   g_free (x_src_offsets);
  3890.   g_free (y_src_offsets);
  3891.   g_free (src);
  3892.   g_free (dest);
  3893. }
  3894.  
  3895.  
  3896. static void
  3897. get_premultiplied_double_row(PixelRegion *srcPR, int x, int y,
  3898.                  int w, double *row, guchar *tmp_src, int n)
  3899. {
  3900.   int b;
  3901.   int bytes = srcPR->bytes;
  3902.   pixel_region_get_row (srcPR, x, y, w, tmp_src, n);
  3903.   if (pixel_region_has_alpha(srcPR))
  3904.   { /* premultiply the alpha into the double array */
  3905.     double *irow = row;
  3906.     int alpha = bytes - 1;
  3907.     double mod_alpha;
  3908.     for (x = 0; x < w; x++)
  3909.     {
  3910.       mod_alpha = tmp_src[alpha] / 255.0;
  3911.       for (b = 0; b < alpha; b++)
  3912.     irow[b] = mod_alpha * tmp_src[b];
  3913.       irow[b] = tmp_src[alpha];
  3914.       irow += bytes;
  3915.       tmp_src += bytes;
  3916.     }
  3917.   }
  3918.   else /* no alpha */
  3919.   {
  3920.     for (x = 0; x <  w*bytes; x++)
  3921.       row[x] = tmp_src[x];
  3922.   }
  3923.  
  3924.   /* set the off edge pixels to their nearest neighbor */
  3925.   for (b = 0; b < 2 * bytes; b++)
  3926.     row[-2*bytes + b] = row[(b%bytes)];
  3927.   for (b = 0; b < bytes * 2; b++)
  3928.     row[w*bytes + b] = row[(w - 1) * bytes + (b%bytes)];
  3929. }
  3930.  
  3931.  
  3932. static
  3933. void expand_line(double *dest, double *src, int bytes,
  3934.          int old_width, int width, InterpolationType interp)
  3935. {
  3936.   double ratio;
  3937.   int x,b;
  3938.   int src_col;
  3939.   double frac;
  3940.   double *s;
  3941.   ratio = old_width/(double)width;
  3942.  
  3943. /* this could be opimized much more by precalculating the coeficients for
  3944.    each x */
  3945.   switch(interp)
  3946.   {
  3947.     case CUBIC_INTERPOLATION:
  3948.       for (x = 0; x < width; x++)
  3949.       {
  3950.     src_col = ((int)((x) * ratio  + 2.0 - 0.5)) - 2;
  3951.     /* +2, -2 is there because (int) rounds towards 0 and we need 
  3952.        to round down */
  3953.     frac =          ((x) * ratio - 0.5) - src_col;
  3954.     s = &src[src_col * bytes];
  3955.     for (b = 0; b < bytes; b++)
  3956.       dest[b] = cubic (frac, s[b - bytes], s[b], s[b+bytes], s[b+bytes*2]);
  3957.     dest += bytes;
  3958.       }
  3959.       break;
  3960.     case LINEAR_INTERPOLATION:
  3961.       for (x = 0; x < width; x++)
  3962.       {
  3963.     src_col = ((int)((x) * ratio + 2.0 - 0.5)) - 2;
  3964.     /* +2, -2 is there because (int) rounds towards 0 and we need 
  3965.        to round down */
  3966.     frac =          ((x) * ratio - 0.5) - src_col;
  3967.     s = &src[src_col * bytes];
  3968.     for (b = 0; b < bytes; b++)
  3969.       dest[b] = ((s[b + bytes] - s[b]) * frac + s[b]);
  3970.     dest += bytes;
  3971.       }
  3972.       break;
  3973.    case NEAREST_NEIGHBOR_INTERPOLATION:
  3974.      g_error("sampling_type can't be "
  3975.          "NEAREST_NEIGHBOR_INTERPOLATION");
  3976.   }
  3977. }
  3978.  
  3979.  
  3980. static void shrink_line(double *dest, double *src, int bytes,
  3981.             int old_width, int width, InterpolationType interp)
  3982. {
  3983.   int x, b;
  3984.   double *source, *destp;
  3985.   register double accum;
  3986.   register unsigned int max;
  3987.   register double mant, tmp;
  3988.   register const double step = old_width/(double)width;
  3989.   register const double inv_step = 1.0/step;
  3990.   double position;
  3991.   for (b = 0; b < bytes; b++)
  3992.   {
  3993.     
  3994.     source = &src[b];
  3995.     destp = &dest[b];
  3996.     position = -1;
  3997.  
  3998.     mant = *source;
  3999.  
  4000.     for (x = 0; x < width; x++)
  4001.     {
  4002.       source+= bytes;
  4003.       accum = 0;
  4004.       max = ((int)(position+step)) - ((int)(position));
  4005.       max--;
  4006.       while (max)
  4007.       {
  4008.     accum += *source;
  4009.     source += bytes;
  4010.     max--;
  4011.       }
  4012.       tmp = accum + mant;
  4013.       mant = ((position+step) - (int)(position + step));
  4014.       mant *= *source;
  4015.       tmp += mant;
  4016.       tmp *= inv_step;
  4017.       mant = *source - mant;
  4018.       *(destp) = tmp;
  4019.       destp += bytes;
  4020.       position += step;
  4021.     
  4022.     }
  4023.   }
  4024. }
  4025.  
  4026. static void
  4027. get_scaled_row(void **src, int y, int new_width, PixelRegion *srcPR, double *row,
  4028.            guchar *src_tmp)
  4029. {
  4030. /* get the necesary lines from the source image, scale them,
  4031.    and put them into src[] */
  4032.   rotate_pointers(src, 4);
  4033.   if (y < 0)
  4034.     y = 0;
  4035.   if (y < srcPR->h)
  4036.   {
  4037.     get_premultiplied_double_row(srcPR, 0, y, srcPR->w,
  4038.                  row, src_tmp, 1);
  4039.     if (new_width > srcPR->w)
  4040.       expand_line(src[3], row, srcPR->bytes, 
  4041.           srcPR->w, new_width, interpolation_type);
  4042.     else if (srcPR->w > new_width)
  4043.       shrink_line(src[3], row, srcPR->bytes, 
  4044.           srcPR->w, new_width, interpolation_type);
  4045.     else /* no scailing needed */
  4046.       memcpy(src[3], row, sizeof (double) * new_width * srcPR->bytes);
  4047.   }
  4048.   else
  4049.     memcpy(src[3], src[2], sizeof (double) * new_width * srcPR->bytes);
  4050. }
  4051. void
  4052. scale_region (PixelRegion *srcPR,
  4053.           PixelRegion *destPR)
  4054. {
  4055.   double  *src[4];
  4056.   guchar * src_tmp;
  4057.   guchar * dest;
  4058.   double * row, *accum;
  4059.   int bytes, b;
  4060.   int width, height;
  4061.   int orig_width, orig_height;
  4062.   double y_rat;
  4063.   int i;
  4064.   int old_y = -4, new_y;
  4065.   int x, y;
  4066.  
  4067.   if (interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION)
  4068.   {
  4069.     scale_region_no_resample (srcPR, destPR);
  4070.     return;
  4071.    }
  4072.  
  4073.   orig_width = srcPR->w;
  4074.   orig_height = srcPR->h;
  4075.  
  4076.   width = destPR->w;
  4077.   height = destPR->h;
  4078.  
  4079.   /*  find the ratios of old y to new y  */
  4080.   y_rat = (double) orig_height / (double) height;
  4081.  
  4082.   bytes = destPR->bytes;
  4083.  
  4084.   /*  the data pointers...  */
  4085.   for (i = 0; i < 4; i++)
  4086.     src[i]    = g_new (double, (width) * bytes);
  4087.   dest   = g_new (guchar, width * bytes);
  4088.  
  4089.   src_tmp = g_new (guchar, orig_width * bytes);
  4090.  
  4091.  /* offset the row pointer by 2*bytes so the range of the array 
  4092.     is [-2*bytes] to [(orig_width + 2)*bytes] */
  4093.   row = g_new(double, (orig_width + 2*2) * bytes);
  4094.   row += bytes*2;
  4095.  
  4096.   accum = g_new(double, (width) * bytes);
  4097.  
  4098.   /*  Scale the selected region  */
  4099.   
  4100.   for (y = 0; y < height;  y++)
  4101.   {
  4102.     if (height < orig_height)
  4103.     {
  4104.       int max;
  4105.       double frac;
  4106.       const double inv_ratio = 1.0 / y_rat;
  4107.       if (y == 0) /* load the first row if this it the first time through  */
  4108.     get_scaled_row((void **)&src[0], 0, width, srcPR, row,
  4109.                src_tmp);
  4110.       new_y = (int)((y) * y_rat);
  4111.       frac = 1.0 - (y*y_rat - new_y);
  4112.       for (x  = 0; x < width*bytes; x++)
  4113.     accum[x] = src[3][x] * frac;
  4114.  
  4115.       max = ((int)((y+1) *y_rat)) - (new_y);
  4116.       max--;
  4117.  
  4118.       get_scaled_row((void **)&src[0], ++new_y, width, srcPR, row,
  4119.              src_tmp);
  4120.       
  4121.       while (max > 0)
  4122.       {
  4123.     for (x  = 0; x < width*bytes; x++)
  4124.       accum[x] += src[3][x];
  4125.     get_scaled_row((void **)&src[0], ++new_y, width, srcPR, row,
  4126.                src_tmp);
  4127.     max--;
  4128.       }
  4129.       frac = (y + 1)*y_rat - ((int)((y + 1)*y_rat));
  4130.       for (x  = 0; x < width*bytes; x++)
  4131.       {
  4132.     accum[x] += frac * src[3][x];
  4133.     accum[x] *= inv_ratio;
  4134.       }
  4135.     }      
  4136.     else if (height > orig_height)
  4137.     {
  4138.       new_y = floor((y) * y_rat - .5);
  4139.     
  4140.       while (old_y <= new_y)
  4141.       { /* get the necesary lines from the source image, scale them,
  4142.        and put them into src[] */
  4143.     get_scaled_row((void **)&src[0], old_y + 2, width, srcPR, row,
  4144.                src_tmp);
  4145.     old_y++;
  4146.       }
  4147.       switch(interpolation_type)
  4148.       {
  4149.        case CUBIC_INTERPOLATION:
  4150.        {
  4151.      double p0, p1, p2, p3;
  4152.      double dy = ((y) * y_rat - .5) - new_y;
  4153.      p0 = cubic(dy, 1, 0, 0, 0);
  4154.      p1 = cubic(dy, 0, 1, 0, 0);
  4155.      p2 = cubic(dy, 0, 0, 1, 0);
  4156.      p3 = cubic(dy, 0, 0, 0, 1);
  4157.      for (x = 0; x < width * bytes; x++)
  4158.        accum[x] = p0 * src[0][x] + p1 * src[1][x] +
  4159.          p2 * src[2][x] + p3 * src[3][x];
  4160.        } break;
  4161.        case LINEAR_INTERPOLATION:
  4162.        {
  4163.      double idy = ((y) * y_rat - 0.5) - new_y;
  4164.      double dy = 1.0 - idy;
  4165.      for (x = 0; x < width * bytes; x++)
  4166.        accum[x] = dy * src[1][x] + idy * src[2][x];
  4167.        } break;
  4168.        case NEAREST_NEIGHBOR_INTERPOLATION:
  4169.      g_error("sampling_type can't be "
  4170.          "NEAREST_NEIGHBOR_INTERPOLATION");
  4171.  
  4172.       }
  4173.     }
  4174.     else /* height == orig_height */
  4175.     {
  4176.       get_scaled_row((void **)&src[0], y, width, srcPR, row,
  4177.              src_tmp);
  4178.       memcpy(accum, src[3], sizeof(double) * width * bytes);
  4179.     }
  4180.     if (pixel_region_has_alpha(srcPR))
  4181.     { /* unmultiply the alpha */
  4182.       double inv_alpha;
  4183.       double *p = accum;
  4184.       int alpha = bytes - 1;
  4185.       int result;
  4186.       guchar *d = dest;
  4187.       for (x = 0; x < width; x++)
  4188.       {
  4189.     if (p[alpha] > 0.001)
  4190.     {
  4191.       inv_alpha = 255.0 / p[alpha];
  4192.       for (b = 0; b < alpha; b++)
  4193.       {
  4194.         result = RINT(inv_alpha * p[b]);
  4195.         if (result < 0)
  4196.           d[b] = 0;
  4197.         else if (result > 255)
  4198.           d[b] = 255;
  4199.         else
  4200.           d[b] = result;
  4201.       }
  4202.       result = RINT(p[alpha]);
  4203.       if (result > 255)
  4204.         d[alpha] = 255;
  4205.       else
  4206.         d[alpha] = result;
  4207.     }
  4208.     else /* alpha <= 0 */
  4209.       for (b = 0; b <= alpha; b++)
  4210.         d[b] = 0;
  4211.     d += bytes;
  4212.     p += bytes;
  4213.  
  4214.       }
  4215.     }
  4216.     else
  4217.     {
  4218.       int w = width * bytes;
  4219.       for (x = 0; x < w; x++)
  4220.       {
  4221.     if (accum[x] < 0.0)
  4222.       dest[x] = 0;
  4223.     else if (accum[x] > 255.0)
  4224.       dest[x] = 255;
  4225.     else
  4226.       dest[x] = RINT(accum[x]);
  4227.       }
  4228.     }
  4229.     pixel_region_set_row (destPR, 0, y, width, dest);
  4230.   }
  4231.  
  4232.   /*  free up temporary arrays  */
  4233.   g_free (accum);
  4234.   for (i = 0; i < 4; i++)
  4235.     g_free (src[i]);
  4236.   g_free (src_tmp);
  4237.   g_free (dest);
  4238.   row -= 2*bytes;
  4239.   g_free (row);
  4240. }
  4241.  
  4242. void
  4243. subsample_region (PixelRegion *srcPR,
  4244.           PixelRegion *destPR,
  4245.           int          subsample)
  4246. {
  4247.   unsigned char * src, * s;
  4248.   unsigned char * dest, * d;
  4249.   double * row, * r;
  4250.   int destwidth;
  4251.   int src_row, src_col;
  4252.   int bytes, b;
  4253.   int width, height;
  4254.   int orig_width, orig_height;
  4255.   double x_rat, y_rat;
  4256.   double x_cum, y_cum;
  4257.   double x_last, y_last;
  4258.   double * x_frac, y_frac, tot_frac;
  4259.   int i, j;
  4260.   int frac;
  4261.   int advance_dest;
  4262.  
  4263.   orig_width = srcPR->w / subsample;
  4264.   orig_height = srcPR->h / subsample;
  4265.   width = destPR->w;
  4266.   height = destPR->h;
  4267.  
  4268.   /*  Some calculations...  */
  4269.   bytes = destPR->bytes;
  4270.   destwidth = destPR->rowstride;
  4271.  
  4272.   /*  the data pointers...  */
  4273.   src = (unsigned char *) g_malloc (orig_width * bytes);
  4274.   dest = destPR->data;
  4275.  
  4276.   /*  find the ratios of old x to new x and old y to new y  */
  4277.   x_rat = (double) orig_width / (double) width;
  4278.   y_rat = (double) orig_height / (double) height;
  4279.  
  4280.   /*  allocate an array to help with the calculations  */
  4281.   row    = (double *) g_malloc (sizeof (double) * width * bytes);
  4282.   x_frac = (double *) g_malloc (sizeof (double) * (width + orig_width));
  4283.  
  4284.   /*  initialize the pre-calculated pixel fraction array  */
  4285.   src_col = 0;
  4286.   x_cum = (double) src_col;
  4287.   x_last = x_cum;
  4288.  
  4289.   for (i = 0; i < width + orig_width; i++)
  4290.     {
  4291.       if (x_cum + x_rat <= (src_col + 1 + EPSILON))
  4292.     {
  4293.       x_cum += x_rat;
  4294.       x_frac[i] = x_cum - x_last;
  4295.     }
  4296.       else
  4297.     {
  4298.       src_col ++;
  4299.       x_frac[i] = src_col - x_last;
  4300.     }
  4301.       x_last += x_frac[i];
  4302.     }
  4303.  
  4304.   /*  clear the "row" array  */
  4305.   memset (row, 0, sizeof (double) * width * bytes);
  4306.  
  4307.   /*  counters...  */
  4308.   src_row = 0;
  4309.   y_cum = (double) src_row;
  4310.   y_last = y_cum;
  4311.  
  4312.   pixel_region_get_row (srcPR, 0, src_row * subsample, orig_width * subsample, src, subsample);
  4313.  
  4314.   /*  Scale the selected region  */
  4315.   for (i = 0; i < height; )
  4316.     {
  4317.       src_col = 0;
  4318.       x_cum = (double) src_col;
  4319.  
  4320.       /* determine the fraction of the src pixel we are using for y */
  4321.       if (y_cum + y_rat <= (src_row + 1 + EPSILON))
  4322.     {
  4323.       y_cum += y_rat;
  4324.       y_frac = y_cum - y_last;
  4325.       advance_dest = TRUE;
  4326.     }
  4327.       else
  4328.     {
  4329.       src_row ++;
  4330.       y_frac = src_row - y_last;
  4331.       advance_dest = FALSE;
  4332.     }
  4333.  
  4334.       y_last += y_frac;
  4335.  
  4336.       s = src;
  4337.       r = row;
  4338.  
  4339.       frac = 0;
  4340.       j = width;
  4341.  
  4342.       while (j)
  4343.     {
  4344.       tot_frac = x_frac[frac++] * y_frac;
  4345.  
  4346.       for (b = 0; b < bytes; b++)
  4347.         r[b] += s[b] * tot_frac;
  4348.  
  4349.       /*  increment the destination  */
  4350.       if (x_cum + x_rat <= (src_col + 1 + EPSILON))
  4351.         {
  4352.           r += bytes;
  4353.           x_cum += x_rat;
  4354.           j--;
  4355.         }
  4356.  
  4357.       /* increment the source */
  4358.       else
  4359.         {
  4360.           s += bytes;
  4361.           src_col++;
  4362.         }
  4363.     }
  4364.  
  4365.       if (advance_dest)
  4366.     {
  4367.       tot_frac = 1.0 / (x_rat * y_rat);
  4368.  
  4369.       /*  copy "row" to "dest"  */
  4370.       d = dest;
  4371.       r = row;
  4372.  
  4373.       j = width;
  4374.       while (j--)
  4375.         {
  4376.           b = bytes;
  4377.           while (b--)
  4378.         *d++ = (unsigned char) (*r++ * tot_frac + 0.5);
  4379.         }
  4380.  
  4381.       dest += destwidth;
  4382.  
  4383.       /*  clear the "row" array  */
  4384.       memset (row, 0, sizeof (double) * destwidth);
  4385.  
  4386.       i++;
  4387.     }
  4388.       else
  4389.     pixel_region_get_row (srcPR, 0, src_row * subsample, orig_width * subsample, src, subsample);
  4390.     }
  4391.  
  4392.   /*  free up temporary arrays  */
  4393.   g_free (row);
  4394.   g_free (x_frac);
  4395.   g_free (src);
  4396. }
  4397.  
  4398.  
  4399. float
  4400. shapeburst_region (PixelRegion *srcPR,
  4401.            PixelRegion *distPR)
  4402. {
  4403.   Tile *tile;
  4404.   unsigned char *tile_data;
  4405.   float max_iterations;
  4406.   float *distp_cur;
  4407.   float *distp_prev;
  4408.   float *tmp;
  4409.   float min_prev;
  4410.   float float_tmp;
  4411.   int min;
  4412.   int min_left;
  4413.   int length;
  4414.   int i, j, k;
  4415.   int src;
  4416.   int fraction;
  4417.   int prev_frac;
  4418.   int x, y;
  4419.   int end;
  4420.   int boundary;
  4421.   int inc;
  4422.  
  4423.   src = 0;
  4424.  
  4425.   max_iterations = 0.0;
  4426.  
  4427.   length = distPR->w + 1;
  4428.   distp_prev = (float *) paint_funcs_get_buffer (sizeof (float) * length * 2);
  4429.   for (i = 0; i < length; i++)
  4430.     distp_prev[i] = 0.0;
  4431.  
  4432.   distp_prev += 1;
  4433.   distp_cur = distp_prev + length;
  4434.  
  4435.   for (i = 0; i < srcPR->h; i++)
  4436.     {
  4437.       /*  set the current dist row to 0's  */
  4438.       memset(distp_cur - 1, 0, sizeof(float) * (length - 1));
  4439.  
  4440.       for (j = 0; j < srcPR->w; j++)
  4441.     {
  4442.       min_prev = MIN (distp_cur[j-1], distp_prev[j]);
  4443.       min_left = MIN ((srcPR->w - j - 1), (srcPR->h - i - 1));
  4444.       min = (int) MIN (min_left, min_prev);
  4445.       fraction = 255;
  4446.  
  4447.       /*  This might need to be changed to 0 instead of k = (min) ? (min - 1) : 0  */
  4448.       for (k = (min) ? (min - 1) : 0; k <= min; k++)
  4449.         {
  4450.           x = j;
  4451.           y = i + k;
  4452.           end = y - k;
  4453.  
  4454.           while (y >= end)
  4455.         {
  4456.           tile = tile_manager_get_tile (srcPR->tiles, x, y, TRUE, FALSE);
  4457.           tile_data = tile_data_pointer (tile, x%TILE_WIDTH, y%TILE_HEIGHT);
  4458.           boundary = MIN ((y % TILE_HEIGHT),
  4459.                   (tile->ewidth - (x % TILE_WIDTH) - 1));
  4460.           boundary = MIN (boundary, (y - end)) + 1;
  4461.           inc = 1 - (tile->ewidth);
  4462.  
  4463.           while (boundary--)
  4464.             {
  4465.               src = *tile_data;
  4466.               if (src == 0)
  4467.             {
  4468.               min = k;
  4469.               y = -1;
  4470.               break;
  4471.             }
  4472.               if (src < fraction)
  4473.             fraction = src;
  4474.  
  4475.               x++;
  4476.               y--;
  4477.               tile_data += inc;
  4478.             }
  4479.  
  4480.           tile_release (tile, FALSE);
  4481.         }
  4482.         }
  4483.  
  4484.       if (src != 0)
  4485.         {
  4486.           /*  If min_left != min_prev use the previous fraction
  4487.            *   if it is less than the one found
  4488.            */
  4489.           if (min_left != min)
  4490.         {
  4491.           prev_frac = (int) (255 * (min_prev - min));
  4492.           if (prev_frac == 255)
  4493.             prev_frac = 0;
  4494.           fraction = MIN (fraction, prev_frac);
  4495.         }
  4496.           min++;
  4497.         }
  4498.  
  4499.       float_tmp = distp_cur[j] = min + fraction / 256.0;
  4500.  
  4501.       if (float_tmp > max_iterations)
  4502.         max_iterations = float_tmp;
  4503.     }
  4504.  
  4505.       /*  set the dist row  */
  4506.       pixel_region_set_row (distPR, distPR->x, distPR->y + i, distPR->w, (unsigned char *) distp_cur);
  4507.  
  4508.       /*  swap pointers around  */
  4509.       tmp = distp_prev;
  4510.       distp_prev = distp_cur;
  4511.       distp_cur = tmp;
  4512.     }
  4513.  
  4514.   return max_iterations;
  4515. }
  4516.  
  4517. static void
  4518. rotate_pointers(void **p, guint32 n)
  4519. {
  4520.   guint32 i;
  4521.   void *tmp;
  4522.   tmp = p[0];
  4523.   for (i = 0; i < n-1; i++)
  4524.   {
  4525.     p[i] = p[i+1];
  4526.   }
  4527.   p[i] = tmp;
  4528. }
  4529.  
  4530. static void
  4531. compute_border(gint16 *circ, guint16 xradius, guint16 yradius)
  4532. {
  4533.   gint32 i;
  4534.   gint32 diameter = xradius*2 +1;
  4535.   gdouble tmp;
  4536.   for (i = 0; i < diameter; i++)
  4537.   {
  4538.     if (i > xradius)
  4539.       tmp = (i - xradius) - .5;
  4540.     else if (i < xradius)
  4541.       tmp = (xradius - i) - .5;
  4542.     else
  4543.       tmp = 0.0;
  4544.     circ[i] = RINT(yradius/(double)xradius *
  4545.            sqrt((xradius)*(xradius) - (tmp)*(tmp)));
  4546.   }
  4547. }
  4548.  
  4549. void
  4550. fatten_region(PixelRegion *src, gint16 xradius, gint16 yradius)
  4551. {
  4552. /*
  4553.   Any bugs in this fuction are probably also in thin_region  
  4554.   Blame all bugs in this function on jaycox@gimp.org
  4555. */
  4556.   register gint32 i, j, x, y;
  4557.   guchar **buf; /* caches the region's pixel data */
  4558.   guchar *out;  /* holds the new scan line we are computing */
  4559.   guchar **max; /* caches the largest values for each column */
  4560.   gint16 *circ; /* holds the y coords of the filter's mask */
  4561.   gint16 last_max, last_index;
  4562.  
  4563.   guchar *buffer;
  4564.  
  4565.   if (xradius <= 0 || yradius <= 0)
  4566.     return;
  4567.  
  4568.   max = (guchar **)g_malloc ((src->w + 2*xradius) * sizeof(void *));
  4569.   buf = (guchar **)g_malloc((yradius + 1) * sizeof(void *));
  4570.   for (i = 0; i < yradius+1; i++)
  4571.   {
  4572.     buf[i] = (guchar *)g_malloc(src->w * sizeof(guchar));
  4573.   }
  4574.   buffer = g_malloc((src->w + 2*xradius)*(yradius + 1) * sizeof(guchar));
  4575.   for (i = 0; i < src->w + 2*xradius; i++)
  4576.   {
  4577.     if (i < xradius)
  4578.       max[i] = buffer;
  4579.     else if (i < src->w + xradius)
  4580.       max[i] = &buffer[(yradius+1)*(i - xradius)];
  4581.     else
  4582.       max[i] = &buffer[(yradius+1)*(src->w + xradius - 1)];
  4583.  
  4584.     for (j = 0 ; j < xradius + 1; j++)
  4585.       max[i][j] = 0;
  4586.   }
  4587.  /* offset the max pointer by xradius so the range of the array 
  4588.     is [-xradius] to [src->w + xradius] */
  4589.   max += xradius;
  4590.  
  4591.   out =  (guchar *)g_malloc (src->w * sizeof(guchar));
  4592.  
  4593.   circ = (short *)g_malloc ((2*xradius + 1) * sizeof(gint16));
  4594.   compute_border (circ, xradius, yradius);
  4595.  
  4596.  /* offset the circ pointer by xradius so the range of the array 
  4597.     is [-xradius] to [xradius] */
  4598.   circ += xradius;
  4599.  
  4600.   memset (buf[0], 0, src->w);
  4601.   for (i = 0; i < yradius && i < src->h; i++) /* load top of image */
  4602.     pixel_region_get_row (src, src->x, src->y + i, src->w, buf[i+1], 1);
  4603.  
  4604.   for (x = 0; x < src->w; x++) /* set up max for top of image */
  4605.   {
  4606.     max[x][0] = 0;         /* buf[0][x] is always 0 */
  4607.     max[x][1] = buf[1][x]; /* MAX (buf[1][x], max[x][0]) always = buf[1][x]*/
  4608.     for (j = 2; j < yradius+1; j++)
  4609.       max[x][j] = MAX(buf[j][x], max[x][j-1]);
  4610.   }
  4611.  
  4612.   for (y = 0; y < src->h; y++)
  4613.   {
  4614.     rotate_pointers((void **)buf, yradius+1);
  4615.     if (y < src->h - (yradius))
  4616.       pixel_region_get_row (src, src->x, src->y + y + yradius, src->w,
  4617.                 buf[yradius], 1);
  4618.     else
  4619.       memset (buf[yradius], 0, src->w);
  4620.     for (x = 0 ; x < src->w; x++) /* update max array */
  4621.     {
  4622.       for (i = yradius; i > 0; i--)
  4623.       {
  4624.     max[x][i] = (MAX (MAX (max[x][i - 1], buf[i-1][x]), buf[i][x]));
  4625.       }
  4626.       max[x][0] = buf[0][x];
  4627.     }
  4628.     last_max =  max[0][circ[-1]];
  4629.     last_index = 1;
  4630.     for (x = 0 ; x < src->w; x++) /* render scan line */
  4631.     {
  4632.       last_index--;
  4633.       if (last_index >= 0)
  4634.       {
  4635.     if (last_max == 255)
  4636.       out[x] = 255;
  4637.     else
  4638.     {
  4639.       last_max = 0;
  4640.       for (i = xradius; i >= 0; i--)
  4641.         if (last_max < max[x+i][circ[i]])
  4642.         {
  4643.           last_max = max[x+i][circ[i]];
  4644.           last_index = i;
  4645.         }
  4646.       out[x] = last_max;
  4647.     }
  4648.       }
  4649.       else
  4650.       {
  4651.     last_index = xradius;
  4652.     last_max = max[x+xradius][circ[xradius]];
  4653.     for (i = xradius-1; i >= -xradius; i--)
  4654.       if (last_max < max[x+i][circ[i]])
  4655.       {
  4656.         last_max = max[x+i][circ[i]];
  4657.         last_index = i;
  4658.       }
  4659.     out[x] = last_max;
  4660.       }
  4661.     }
  4662.     pixel_region_set_row (src, src->x, src->y + y, src->w, out);
  4663.   }
  4664.   /* undo the offsets to the pointers so we can free the malloced memmory */
  4665.   circ -= xradius;
  4666.   max -= xradius;
  4667.  
  4668.   g_free (circ);
  4669.   g_free (buffer);
  4670.   g_free (max);
  4671.   for (i = 0; i < yradius + 1; i++)
  4672.     g_free (buf[i]);
  4673.   g_free (buf);
  4674.   g_free (out);
  4675. }
  4676.  
  4677. void
  4678. thin_region(PixelRegion *src, gint16 xradius, gint16 yradius, int edge_lock)
  4679. {
  4680. /*
  4681.   pretty much the same as fatten_region only different
  4682.   blame all bugs in this function on jaycox@gimp.org
  4683. */
  4684.   /* If edge_lock is true  we assume that pixels outside the region
  4685.      we are passed are identical to the edge pixels.
  4686.      If edge_lock is false, we assume that pixels outside the region are 0
  4687.   */
  4688.   register gint32 i, j, x, y;
  4689.   guchar **buf; /* caches the the region's pixels */
  4690.   guchar *out;  /* holds the new scan line we are computing */
  4691.   guchar **max; /* caches the smallest values for each column */
  4692.   gint16 *circ; /* holds the y coords of the filter's mask */
  4693.   gint16 last_max, last_index;
  4694.  
  4695.   guchar *buffer;
  4696.  
  4697.   if (xradius <= 0 || yradius <= 0)
  4698.     return;
  4699.  
  4700.   max = (guchar **)g_malloc ((src->w+2*xradius) * sizeof(void *));
  4701.   buf = (guchar **)g_malloc ((yradius+1) * sizeof(void *));
  4702.   for (i = 0; i < yradius+1; i++)
  4703.   {
  4704.     buf[i] = (guchar *)g_malloc (src->w * sizeof(guchar));
  4705.   }
  4706.   buffer = g_malloc ((src->w+2*xradius + 1)*(yradius+1));
  4707.   if (edge_lock)
  4708.     memset(buffer, 255, (src->w+2*xradius + 1)*(yradius+1));
  4709.   else
  4710.     memset(buffer, 0, (src->w+2*xradius + 1)*(yradius+1));
  4711.   for (i = 0; i < src->w+2*xradius; i++)
  4712.   {
  4713.     if (i < xradius)
  4714.       if (edge_lock)
  4715.     max[i] = buffer;
  4716.       else
  4717.     max[i] = &buffer[(yradius+1)*(src->w + xradius)];
  4718.     else if (i < src->w + xradius)
  4719.       max[i] = &buffer[(yradius+1)*(i - xradius)];
  4720.     else
  4721.       if (edge_lock)
  4722.     max[i] = &buffer[(yradius+1)*(src->w + xradius - 1)];
  4723.       else
  4724.     max[i] = &buffer[(yradius+1)*(src->w + xradius)];
  4725.   }
  4726.   if (!edge_lock)
  4727.     for (j = 0 ; j < xradius+1; j++)
  4728.       max[0][j] = 0;
  4729.  
  4730.  /* offset the max pointer by xradius so the range of the array 
  4731.     is [-xradius] to [src->w + xradius] */
  4732.   max += xradius;
  4733.  
  4734.   out = (guchar *)g_malloc(src->w);
  4735.  
  4736.   circ = (short *)g_malloc((2*xradius + 1)*sizeof(gint16));
  4737.   compute_border(circ, xradius, yradius);
  4738.  
  4739.  /* offset the circ pointer by xradius so the range of the array 
  4740.     is [-xradius] to [xradius] */
  4741.   circ += xradius;
  4742.  
  4743.   for (i = 0; i < yradius && i < src->h; i++) /* load top of image */
  4744.     pixel_region_get_row (src, src->x, src->y + i, src->w, buf[i+1], 1);
  4745.   if (edge_lock)
  4746.     memcpy (buf[0], buf[1], src->w);
  4747.   else
  4748.     memset (buf[0], 0, src->w);
  4749.  
  4750.   for (x = 0; x < src->w; x++) /* set up max for top of image */
  4751.   {
  4752.     max[x][0] = buf[0][x];
  4753.     for (j = 1; j < yradius+1; j++)
  4754.       max[x][j] = MIN(buf[j][x], max[x][j-1]);
  4755.   }
  4756.  
  4757.   for (y = 0; y < src->h; y++)
  4758.   {
  4759.     rotate_pointers ((void **)buf, yradius+1);
  4760.     if (y < src->h - (yradius))
  4761.       pixel_region_get_row (src, src->x, src->y + y + yradius, src->w,
  4762.                 buf[yradius], 1);
  4763.     else if (edge_lock)
  4764.       memcpy (buf[yradius], buf[yradius -1], src->w);
  4765.     else
  4766.       memset (buf[yradius], 0, src->w);
  4767.     for (x = 0 ; x < src->w; x++) /* update max array */
  4768.     {
  4769.       for (i = yradius; i > 0; i--)
  4770.       {
  4771.     max[x][i] = (MIN (MIN (max[x][i - 1], buf[i-1][x]), buf[i][x]));
  4772.       }
  4773.       max[x][0] = buf[0][x];
  4774.     }
  4775.     last_max =  max[0][circ[-1]];
  4776.     last_index = 0;
  4777.     for (x = 0 ; x < src->w; x++) /* render scan line */
  4778.     {
  4779.       last_index--;
  4780.       if (last_index >= 0)
  4781.       {
  4782.     if (last_max == 0)
  4783.       out[x] = 0;
  4784.     else
  4785.     {
  4786.       last_max = 255;
  4787.       for (i = xradius; i >= 0; i--)
  4788.         if (last_max > max[x+i][circ[i]])
  4789.         {
  4790.           last_max = max[x+i][circ[i]];
  4791.           last_index = i;
  4792.         }
  4793.       out[x] = last_max;
  4794.     }
  4795.       }
  4796.       else
  4797.       {
  4798.     last_index = xradius;
  4799.     last_max = max[x+xradius][circ[xradius]];
  4800.     for (i = xradius-1; i >= -xradius; i--)
  4801.       if (last_max > max[x+i][circ[i]])
  4802.       {
  4803.         last_max = max[x+i][circ[i]];
  4804.         last_index = i;
  4805.       }
  4806.     out[x] = last_max;
  4807.       }
  4808.     }
  4809.     pixel_region_set_row (src, src->x, src->y + y, src->w, out);
  4810.   }
  4811.   /* undo the offsets to the pointers so we can free the malloced memmory */
  4812.   circ -= xradius;
  4813.   max -= xradius;
  4814.   /* free the memmory */
  4815.   g_free (circ);
  4816.   g_free (buffer);
  4817.   g_free (max);
  4818.   for (i = 0; i < yradius + 1; i++)
  4819.     g_free (buf[i]);
  4820.   g_free (buf);
  4821.   g_free (out);
  4822. }
  4823.  
  4824. static void
  4825. compute_transition(guchar *transition, guchar **buf, gint32 width)
  4826. {
  4827.   register gint32 x = 0;
  4828.   if (width == 1)
  4829.   {
  4830.     if (buf[1][x] > 127 && (buf[0][x] < 128 || buf[2][x] < 128))
  4831.       transition[x] = 255;
  4832.     else
  4833.       transition[x] = 0;
  4834.     return;
  4835.   }
  4836.   if (buf[1][x] > 127)
  4837.   {
  4838.     if ( buf[0][x] < 128 || buf[0][x+1] < 128 ||
  4839.                         buf[1][x+1] < 128 ||
  4840.      buf[2][x] < 128 || buf[2][x+1] < 128 )
  4841.       transition[x] = 255;
  4842.     else
  4843.       transition[x] = 0;
  4844.   }
  4845.   else
  4846.     transition[x] = 0;
  4847.   for (x = 1; x < width - 1; x++)
  4848.   {
  4849.     if (buf[1][x] >= 128)
  4850.     {
  4851.       if (buf[0][x-1] < 128 || buf[0][x] < 128 || buf[0][x+1] < 128 ||
  4852.       buf[1][x-1] < 128           ||          buf[1][x+1] < 128 ||
  4853.       buf[2][x-1] < 128 || buf[2][x] < 128 || buf[2][x+1] < 128)
  4854.     transition[x] = 255;
  4855.       else
  4856.     transition[x] = 0;
  4857.     }
  4858.     else
  4859.       transition[x] = 0;
  4860.   }
  4861.   if (buf[1][x] >= 128)
  4862.   {
  4863.     if ( buf[0][x-1] < 128 || buf[0][x] < 128 ||
  4864.      buf[1][x-1] < 128 ||
  4865.      buf[2][x-1] < 128 || buf[2][x] < 128)
  4866.       transition[x] = 255;
  4867.     else
  4868.       transition[x] = 0;
  4869.   }
  4870.   else
  4871.     transition[x] = 0;
  4872. }
  4873.  
  4874. void
  4875. border_region(PixelRegion *src, gint16 xradius, gint16 yradius)
  4876. {
  4877. /*
  4878.   This function has no bugs, but if you imagine some you can
  4879.   blame them on jaycox@gimp.org
  4880. */
  4881.   register gint32 i, j, x, y;
  4882.   guchar **buf, *out;
  4883.   gint16 *max;
  4884.   guchar **density;
  4885.   guchar **transition;
  4886.   guchar last_max;
  4887.   gint16 last_index;
  4888.  
  4889.   if (xradius < 0 || yradius < 0)
  4890.   {
  4891.     g_warning ("border_region: negative radius specified.");
  4892.     return;
  4893.   }
  4894.   if (xradius == 0 || yradius == 0)
  4895.   {
  4896.     unsigned char color[] = "\0\0\0\0";
  4897.     color_region(src, color);
  4898.     return;
  4899.   }
  4900.   if (xradius == 1 && yradius == 1) /* optimize this case specifically */
  4901.   {
  4902.     guchar *transition;
  4903.     guchar *source[3];
  4904.     for (i = 0; i < 3; i++)
  4905.       source[i] = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4906.  
  4907.     transition = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4908.  
  4909.     pixel_region_get_row (src, src->x, src->y + 0, src->w, source[0], 1);
  4910.     memcpy (source[1], source[0], src->w);
  4911.     if (src->h > 1)
  4912.       pixel_region_get_row (src, src->x, src->y + 1, src->w, source[2], 1);
  4913.     else
  4914.       memcpy (source[2], source[1], src->w);
  4915.  
  4916.     compute_transition (transition, source, src->w);
  4917.     pixel_region_set_row (src, src->x, src->y , src->w, transition);
  4918.     
  4919.     for (y = 1; y < src->h; y++)
  4920.     {
  4921.       rotate_pointers ((void **)source, 3);
  4922.       if (y +1 < src->h)
  4923.     pixel_region_get_row (src, src->x, src->y +y +1, src->w, source[2], 1);
  4924.       else
  4925.     memcpy(source[2], source[1], src->w);
  4926.       compute_transition (transition, source, src->w);
  4927.       pixel_region_set_row (src, src->x, src->y + y, src->w, transition);
  4928.       
  4929.     }
  4930.     for (i = 0; i < 3; i++)
  4931.       g_free(source[i]);
  4932.     g_free(transition);
  4933.     return;
  4934.   } /* end of if (xradius == 1 && yradius == 1) */
  4935.   max = (gint16 *)g_malloc ((src->w+2*xradius)*sizeof(gint16 *));
  4936.   for (i = 0; i < (src->w+2*xradius); i++)
  4937.     max[i] = yradius+2;
  4938.   max += xradius;
  4939.  
  4940.   buf = (guchar **)g_malloc ((3)*sizeof(void *));
  4941.   for (i = 0; i < 3; i++)
  4942.   {
  4943.     buf[i] = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4944.   }
  4945.   transition = (guchar **)g_malloc ((yradius+1)*sizeof(void*));
  4946.   for (i = 0; i < yradius +1; i++)
  4947.   {
  4948.     transition[i] = (guchar *)g_malloc (src->w+2*xradius);
  4949.     memset(transition[i], 0, src->w+2*xradius);
  4950.     transition[i] += xradius;
  4951.   }
  4952.   out = (guchar *)g_malloc ((src->w)*sizeof(guchar));
  4953.   density = (guchar **)g_malloc ((2*xradius + 1)*sizeof(void *));
  4954.   density += xradius;
  4955.  
  4956.   for (x = 0; x < (xradius+1); x++) /* allocate density[][] */
  4957.   {
  4958.     density[ x]  = (guchar *)g_malloc (2*yradius +1);
  4959.     density[ x] += yradius;
  4960.     density[-x]  = density[x];
  4961.   }
  4962.   for (x = 0; x < (xradius+1); x++) /* compute density[][] */
  4963.   {
  4964.     register double tmpx, tmpy, dist;
  4965.     guchar a;
  4966.     if (x > 0)
  4967.       tmpx = x - 0.5;
  4968.     else if (x < 0)
  4969.       tmpx = x + 0.5;
  4970.     else
  4971.       tmpx = 0.0;
  4972.     for (y = 0; y < (yradius+1); y++)
  4973.     {
  4974.       if (y > 0)
  4975.     tmpy = y - 0.5;
  4976.       else if (y < 0)
  4977.     tmpy = y + 0.5;
  4978.       else
  4979.     tmpy = 0.0;
  4980.       dist = (tmpy*tmpy)/(yradius*yradius) + (tmpx*tmpx)/(xradius*xradius);
  4981.       if (dist < 1.0)
  4982.     a = 255*(1.0 - sqrt (dist));
  4983.       else
  4984.     a = 0;
  4985.       density[ x][ y] = a;
  4986.       density[ x][-y] = a;
  4987.       density[-x][ y] = a;
  4988.       density[-x][-y] = a;
  4989.     }
  4990.   }
  4991.   pixel_region_get_row (src, src->x, src->y + 0, src->w, buf[0], 1);
  4992.   memcpy (buf[1], buf[0], src->w);
  4993.   if (src->h > 1)
  4994.     pixel_region_get_row (src, src->x, src->y + 1, src->w, buf[2], 1);
  4995.   else
  4996.     memcpy (buf[2], buf[1], src->w);
  4997.   compute_transition (transition[1], buf, src->w);
  4998.  
  4999.   for (y = 1; y < yradius && y + 1< src->h; y++) /* set up top of image */
  5000.   {
  5001.     rotate_pointers ((void **)buf, 3);
  5002.     pixel_region_get_row (src, src->x, src->y + y + 1, src->w, buf[2], 1);
  5003.     compute_transition (transition[y + 1], buf, src->w);
  5004.   }
  5005.   for (x = 0; x < src->w; x++) /* set up max[] for top of image */
  5006.   {
  5007.     max[x] = -(yradius+7); 
  5008.     for (j = 1; j < yradius+1; j++)
  5009.       if (transition[j][x])
  5010.       {
  5011.     max[x] = j;
  5012.     break;
  5013.       }
  5014.   }
  5015.   for (y = 0; y < src->h; y++) /* main calculation loop */
  5016.   {
  5017.     rotate_pointers ((void **)buf, 3);
  5018.     rotate_pointers ((void **)transition, yradius + 1);
  5019.     if (y < src->h - (yradius+1))
  5020.     {
  5021.       pixel_region_get_row (src, src->x, src->y + y + yradius + 1, src->w,
  5022.                 buf[2], 1);
  5023.       compute_transition (transition[yradius], buf, src->w);
  5024.     }
  5025.     else
  5026.       memcpy (transition[yradius], transition[yradius - 1], src->w);
  5027.  
  5028.     for (x = 0; x < src->w; x++) /* update max array */
  5029.     {
  5030.       if (max[x] < 1)
  5031.       {
  5032.     if (max[x] <= -yradius)
  5033.     {
  5034.       if (transition[yradius][x])
  5035.         max[x] = yradius;
  5036.       else
  5037.         max[x]--;
  5038.     }
  5039.     else
  5040.       if (transition[-max[x]][x])
  5041.         max[x] = -max[x];
  5042.       else if (transition[-max[x]+1][x])
  5043.         max[x] = -max[x]+1;
  5044.       else
  5045.         max[x]--;
  5046.       }
  5047.       else
  5048.     max[x]--;
  5049.       if (max[x] < -yradius - 1)
  5050.     max[x] = -yradius -1;
  5051.     }
  5052.     last_max =  max[0][density[-1]];
  5053.     last_index = 1;
  5054.     for (x = 0 ; x < src->w; x++) /* render scan line */
  5055.     {
  5056.       last_index--;
  5057.       if (last_index >= 0)
  5058.       {
  5059.     last_max = 0;
  5060.     for (i = xradius; i >= 0; i--)
  5061.       if (max[x+i] <= yradius && max[x+i] >= -yradius &&
  5062.           density[i][max[x+i]] > last_max)
  5063.       {
  5064.         last_max = density[i][max[x+i]];
  5065.         last_index = i;
  5066.       }
  5067.     out[x] = last_max;
  5068.       }
  5069.       else
  5070.       {
  5071.     last_max = 0;
  5072.     for (i = xradius; i >= -xradius; i--)
  5073.       if (max[x+i] <= yradius && max[x+i] >= -yradius &&
  5074.           density[i][max[x+i]] > last_max)
  5075.       {
  5076.         last_max = density[i][max[x+i]];
  5077.         last_index = i;
  5078.       }
  5079.     out[x] = last_max;
  5080.       }
  5081.       if (last_max == 0)
  5082.       {
  5083.     for (i = x+1; i < src->w; i++)
  5084.     {
  5085.       if (max[i] >= -yradius)
  5086.         break;
  5087.     }
  5088.     if (i - x > xradius)
  5089.     {
  5090.       for (; x < i - xradius; x++)
  5091.         out[x] = 0;
  5092.       x--;
  5093.     }
  5094.     last_index = xradius;
  5095.       }
  5096.     }
  5097.     pixel_region_set_row (src, src->x, src->y + y, src->w, out);
  5098.   }
  5099.   g_free(out);
  5100.  
  5101.   for (i = 0; i < 3; i++)
  5102.     g_free(buf[i]);
  5103.  
  5104.   g_free (buf);
  5105.   max -= xradius;
  5106.   g_free (max);
  5107.  
  5108.   for (i = 0; i < yradius +1; i++)
  5109.   {
  5110.     transition[i] -= xradius;
  5111.     g_free (transition[i]);
  5112.   }
  5113.   g_free (transition);
  5114.  
  5115.   for (i = 0; i < xradius +1 ; i++)
  5116.   {
  5117.     density[i]-= yradius;
  5118.     g_free(density[i]);
  5119.   }
  5120.   density -= xradius;
  5121.   g_free(density);
  5122. }
  5123.  
  5124. void
  5125. swap_region (PixelRegion *src,
  5126.          PixelRegion *dest)
  5127. {
  5128.   int h;
  5129.   int length;
  5130.   unsigned char * s, * d;
  5131.   void * pr;
  5132.  
  5133.   for (pr = pixel_regions_register (2, src, dest); pr != NULL; pr = pixel_regions_process (pr))
  5134.     {
  5135.       s = src->data;
  5136.       h = src->h;
  5137.       d = dest->data;
  5138.       length = src->w * src->bytes;
  5139.  
  5140.       while (h --)
  5141.     {
  5142.       swap_pixels (s, d, length);
  5143.       s += src->rowstride;
  5144.       d += dest->rowstride;
  5145.     }
  5146.     }
  5147. }
  5148.  
  5149.  
  5150. static void
  5151. apply_mask_to_sub_region (int *opacityp,
  5152.               PixelRegion *src,
  5153.               PixelRegion *mask)
  5154. {
  5155.   int h;
  5156.   unsigned char * s, * m;
  5157.   int opacity = *opacityp;
  5158.   
  5159.   s = src->data;
  5160.   m = mask->data;
  5161.   h = src->h;
  5162.  
  5163.   while (h --)
  5164.   {
  5165.     apply_mask_to_alpha_channel (s, m, opacity, src->w, src->bytes);
  5166.     s += src->rowstride;
  5167.     m += mask->rowstride;
  5168.   }
  5169. }
  5170.  
  5171. void
  5172. apply_mask_to_region (PixelRegion *src,
  5173.               PixelRegion *mask,
  5174.               int          opacity)
  5175. {
  5176.   pixel_regions_process_parallel ((p_func)apply_mask_to_sub_region,
  5177.                   &opacity, 2, src, mask);
  5178. }
  5179.  
  5180.  
  5181. static void
  5182. combine_mask_and_sub_region (int *opacityp,
  5183.                  PixelRegion *src,
  5184.                  PixelRegion *mask)
  5185. {
  5186.   int h;
  5187.   unsigned char * s, * m;
  5188.   int opacity = *opacityp;
  5189.   
  5190.   s = src->data;
  5191.   m = mask->data;
  5192.   h = src->h;
  5193.  
  5194.   while (h --)
  5195.   {
  5196.     combine_mask_and_alpha_channel (s, m, opacity, src->w, src->bytes);
  5197.     s += src->rowstride;
  5198.     m += mask->rowstride;
  5199.   }
  5200. }
  5201.  
  5202. void
  5203. combine_mask_and_region (PixelRegion *src,
  5204.              PixelRegion *mask,
  5205.              int          opacity)
  5206. {
  5207.  
  5208.   pixel_regions_process_parallel ((p_func)combine_mask_and_sub_region,
  5209.                   &opacity, 2, src, mask);
  5210. }
  5211.  
  5212.  
  5213. void
  5214. copy_gray_to_region (PixelRegion *src,
  5215.              PixelRegion *dest)
  5216. {
  5217.   int h;
  5218.   unsigned char * s, * d;
  5219.   void * pr;
  5220.  
  5221.   for (pr = pixel_regions_register (2, src, dest); pr != NULL; pr = pixel_regions_process (pr))
  5222.     {
  5223.       s = src->data;
  5224.       d = dest->data;
  5225.       h = src->h;
  5226.  
  5227.       while (h --)
  5228.     {
  5229.       copy_gray_to_inten_a_pixels (s, d, src->w, dest->bytes);
  5230.       s += src->rowstride;
  5231.       d += dest->rowstride;
  5232.     }
  5233.     }
  5234. }
  5235.  
  5236.  
  5237. struct initial_regions_struct
  5238. {
  5239.   int opacity;
  5240.   LayerModeEffects mode;
  5241.   int *affect;
  5242.   int type;
  5243.   unsigned char *data;
  5244. };
  5245.  
  5246. void
  5247. initial_sub_region(struct initial_regions_struct *st, 
  5248.            PixelRegion   *src,
  5249.            PixelRegion   *dest,
  5250.            PixelRegion   *mask)
  5251. {
  5252.   int h;
  5253.   unsigned char * s, * d, * m;
  5254.   unsigned char    buf[MAX (src->w * (src->bytes + 1),
  5255.                             dest->w * dest->bytes)];
  5256.   unsigned char   *data;
  5257.   int              opacity;
  5258.   LayerModeEffects mode;
  5259.   int             *affect;
  5260.   int              type;
  5261.  
  5262.   data = st->data;
  5263.   opacity = st->opacity;
  5264.   mode = st->mode;
  5265.   affect = st->affect;
  5266.   type = st->type;
  5267.  
  5268.   if (src->w * (src->bytes + 1) > sizeof (buf))
  5269.     g_error ("initial_sub_region:: error :: src->w * (src->bytes + 1) > sizeof (buf)\n");
  5270.  
  5271.   s = src->data;
  5272.   d = dest->data;
  5273.   m = (mask) ? mask->data : NULL;
  5274.  
  5275.   for (h = 0; h < src->h; h++)
  5276.   {
  5277.     /*  based on the type of the initial image...  */
  5278.     switch (type)
  5279.     {
  5280.      case INITIAL_CHANNEL_MASK:
  5281.      case INITIAL_CHANNEL_SELECTION:
  5282.        initial_channel_pixels (s, d, src->w, dest->bytes);
  5283.        break;
  5284.  
  5285.      case INITIAL_INDEXED:
  5286.        initial_indexed_pixels (s, d, data, src->w);
  5287.        break;
  5288.  
  5289.      case INITIAL_INDEXED_ALPHA:
  5290.        initial_indexed_a_pixels (s, d, m, data, opacity, src->w);
  5291.        break;
  5292.  
  5293.      case INITIAL_INTENSITY:
  5294.        if (mode == DISSOLVE_MODE)
  5295.        {
  5296.      dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
  5297.               src->bytes + 1, 0);
  5298.      initial_inten_pixels (buf, d, m, opacity, affect,
  5299.                    src->w, src->bytes);
  5300.        }
  5301.        else
  5302.      initial_inten_pixels (s, d, m, opacity, affect, src->w, src->bytes);
  5303.        break;
  5304.  
  5305.      case INITIAL_INTENSITY_ALPHA:
  5306.        if (mode == DISSOLVE_MODE)
  5307.        {
  5308.      dissolve_pixels (s, buf, src->x, src->y + h, opacity, src->w, src->bytes,
  5309.               src->bytes, 1);
  5310.      initial_inten_a_pixels (buf, d, m, opacity, affect,
  5311.                  src->w, src->bytes);
  5312.        }
  5313.        else
  5314.      initial_inten_a_pixels (s, d, m, opacity, affect, src->w, src->bytes);
  5315.        break;
  5316.     }
  5317.  
  5318.     s += src->rowstride;
  5319.     d += dest->rowstride;
  5320.     if (mask)
  5321.       m += mask->rowstride;
  5322.   }
  5323. }
  5324.  
  5325. void
  5326. initial_region (PixelRegion    *src,
  5327.         PixelRegion    *dest,
  5328.         PixelRegion    *mask,
  5329.         unsigned char    *data,
  5330.         int         opacity,
  5331.         LayerModeEffects mode,
  5332.         int        *affect,
  5333.         int         type)
  5334. {
  5335.   struct initial_regions_struct st;
  5336.  
  5337.   st.opacity = opacity;
  5338.   st.mode = mode;
  5339.   st.affect = affect;
  5340.   st.type = type;
  5341.   st.data = data;
  5342.   
  5343.   pixel_regions_process_parallel ((p_func)initial_sub_region, &st, 3,
  5344.                     src, dest, mask);
  5345. }
  5346.  
  5347. struct combine_regions_struct
  5348. {
  5349.   int opacity;
  5350.   LayerModeEffects mode;
  5351.   int *affect;
  5352.   int type;
  5353.   unsigned char *data;
  5354.   int has_alpha1, has_alpha2;
  5355.   gboolean opacity_quickskip_possible;
  5356.   gboolean transparency_quickskip_possible;
  5357. };
  5358.  
  5359.  
  5360.  
  5361. void
  5362. combine_sub_region(struct combine_regions_struct *st,
  5363.            PixelRegion *src1, PixelRegion *src2,
  5364.            PixelRegion *dest, PixelRegion *mask)
  5365. {
  5366.   unsigned char   *data;
  5367.   int              opacity;
  5368.   LayerModeEffects mode;
  5369.   int             *affect;
  5370.   int              type;
  5371.   int h;
  5372.   int has_alpha1, has_alpha2;
  5373.   int combine = 0;
  5374.   int mode_affect;
  5375.   unsigned char * s, * s1, * s2;
  5376.   unsigned char * d, * m;
  5377.   unsigned char buf[MAX (MAX (src1->w * src1->bytes,
  5378.                               src2->w * src2->bytes),
  5379.                          dest->w * dest->bytes)];
  5380.   gboolean opacity_quickskip_possible;
  5381.   gboolean transparency_quickskip_possible;
  5382.   TileRowHint hint;
  5383.  
  5384.   opacity = st->opacity;
  5385.   mode = st->mode;
  5386.   affect = st->affect;
  5387.   type = st->type;
  5388.   data = st->data;
  5389.   has_alpha1 = st->has_alpha1;
  5390.   has_alpha2 = st->has_alpha2;
  5391.  
  5392.   opacity_quickskip_possible = (st->opacity_quickskip_possible &&
  5393.                 src2->tiles);
  5394.   transparency_quickskip_possible = (st->transparency_quickskip_possible &&
  5395.                      src2->tiles);
  5396.  
  5397.   s1 = src1->data;
  5398.   s2 = src2->data;
  5399.   d = dest->data;
  5400.   m = (mask) ? mask->data : NULL;
  5401.  
  5402.   if (src1->w * src1->bytes > sizeof (buf))
  5403.     g_error ("combine_sub_region::src1->w * src1->bytes > sizeof (buf)\n");
  5404.  
  5405.   if (transparency_quickskip_possible || opacity_quickskip_possible)
  5406.     {
  5407. #ifdef HINTS_SANITY
  5408.       if (src1->h != src2->h)
  5409.     g_error("HEIGHTS SUCK!!");
  5410.       if (src1->offy != dest->offy)
  5411.     g_error("SRC1 OFFSET != DEST OFFSET");
  5412. #endif
  5413.       update_tile_rowhints (src2->curtile,
  5414.                 src2->offy, src2->offy + (src1->h - 1));
  5415.     }
  5416.   /* else it's probably a brush-composite */
  5417.  
  5418.   for (h = 0; h < src1->h; h++)
  5419.     {
  5420.       hint = TILEROWHINT_UNDEFINED;
  5421.  
  5422.       if (transparency_quickskip_possible)
  5423.     {
  5424.       hint = tile_get_rowhint (src2->curtile, (src2->offy + h));
  5425.  
  5426.       if (hint == TILEROWHINT_TRANSPARENT)
  5427.         {
  5428.           goto next_row;
  5429.         }
  5430.     }
  5431.       else
  5432.     {
  5433.       if (opacity_quickskip_possible)
  5434.         {
  5435.           hint = tile_get_rowhint (src2->curtile, (src2->offy + h));
  5436.         }
  5437.     }
  5438.       
  5439.       s = buf;
  5440.  
  5441.       /*  apply the paint mode based on the combination type & mode  */
  5442.       switch (type)
  5443.     {
  5444.     case COMBINE_INTEN_A_INDEXED_A:
  5445.     case COMBINE_INTEN_A_CHANNEL_MASK:
  5446.     case COMBINE_INTEN_A_CHANNEL_SELECTION:
  5447.       combine = type;
  5448.       break;
  5449.  
  5450.     case COMBINE_INDEXED_INDEXED:
  5451.     case COMBINE_INDEXED_INDEXED_A:
  5452.     case COMBINE_INDEXED_A_INDEXED_A:
  5453.       /*  Now, apply the paint mode--for indexed images  */
  5454.       combine = apply_indexed_layer_mode (s1, s2, &s, mode,
  5455.                           has_alpha1, has_alpha2);
  5456.       break;
  5457.  
  5458.     case COMBINE_INTEN_INTEN_A:
  5459.     case COMBINE_INTEN_A_INTEN:
  5460.     case COMBINE_INTEN_INTEN:
  5461.     case COMBINE_INTEN_A_INTEN_A:
  5462.       /*  Now, apply the paint mode  */
  5463.       combine = apply_layer_mode (s1, s2, &s, src1->x, src1->y + h,
  5464.                       opacity, src1->w, mode,
  5465.                       src1->bytes, src2->bytes,
  5466.                       has_alpha1, has_alpha2, &mode_affect);
  5467.       break;
  5468.  
  5469.     default:
  5470.       g_warning ("combine_sub_region: unhandled combine-type.");
  5471.       break;
  5472.     }
  5473.  
  5474.       /*  based on the type of the initial image...  */
  5475.       switch (combine)
  5476.     {
  5477.     case COMBINE_INDEXED_INDEXED:
  5478.       combine_indexed_and_indexed_pixels (s1, s2, d, m, opacity,
  5479.                           affect, src1->w,
  5480.                           src1->bytes);
  5481.       break;
  5482.         
  5483.     case COMBINE_INDEXED_INDEXED_A:
  5484.       combine_indexed_and_indexed_a_pixels (s1, s2, d, m, opacity,
  5485.                         affect, src1->w,
  5486.                         src1->bytes);
  5487.       break;
  5488.         
  5489.     case COMBINE_INDEXED_A_INDEXED_A:
  5490.       combine_indexed_a_and_indexed_a_pixels (s1, s2, d, m, opacity,
  5491.                           affect, src1->w,
  5492.                           src1->bytes);
  5493.       break;
  5494.         
  5495.     case COMBINE_INTEN_A_INDEXED_A:
  5496.       /*  assume the data passed to this procedure is the
  5497.        *  indexed layer's colormap
  5498.        */
  5499.       combine_inten_a_and_indexed_a_pixels (s1, s2, d, m, data, opacity,
  5500.                         src1->w, dest->bytes);
  5501.       break;
  5502.         
  5503.     case COMBINE_INTEN_A_CHANNEL_MASK:
  5504.       /*  assume the data passed to this procedure is the
  5505.        *  indexed layer's colormap
  5506.        */
  5507.       combine_inten_a_and_channel_mask_pixels (s1, s2, d, data, opacity,
  5508.                            src1->w, dest->bytes);
  5509.       break;
  5510.         
  5511.     case COMBINE_INTEN_A_CHANNEL_SELECTION:
  5512.       combine_inten_a_and_channel_selection_pixels (s1, s2, d, data,
  5513.                             opacity,
  5514.                             src1->w,
  5515.                             src1->bytes);
  5516.       break;
  5517.         
  5518.     case COMBINE_INTEN_INTEN:
  5519.       if ((hint == TILEROWHINT_OPAQUE) &&
  5520.           opacity_quickskip_possible)
  5521.         {
  5522.           memcpy (d, s, dest->w * dest->bytes);
  5523.         }
  5524.       else
  5525.         combine_inten_and_inten_pixels (s1, s, d, m, opacity,
  5526.                         affect, src1->w, src1->bytes);
  5527.       break;
  5528.         
  5529.     case COMBINE_INTEN_INTEN_A:
  5530.       combine_inten_and_inten_a_pixels (s1, s, d, m, opacity,
  5531.                         affect, src1->w, src1->bytes);
  5532.       break;
  5533.         
  5534.     case COMBINE_INTEN_A_INTEN:
  5535.       combine_inten_a_and_inten_pixels (s1, s, d, m, opacity,
  5536.                         affect, mode_affect, src1->w,
  5537.                         src1->bytes);
  5538.       break;
  5539.         
  5540.     case COMBINE_INTEN_A_INTEN_A:
  5541.       if ((hint == TILEROWHINT_OPAQUE) &&
  5542.           opacity_quickskip_possible)
  5543.         {
  5544.           memcpy (d, s, dest->w * dest->bytes);
  5545.         }
  5546.       else
  5547.         combine_inten_a_and_inten_a_pixels (s1, s, d, m, opacity,
  5548.                         affect, mode_affect,
  5549.                         src1->w, src1->bytes);
  5550.       break;
  5551.         
  5552.     case BEHIND_INTEN:
  5553.       behind_inten_pixels (s1, s, d, m, opacity,
  5554.                    affect, src1->w, src1->bytes,
  5555.                    src2->bytes, has_alpha1, has_alpha2);
  5556.       break;
  5557.         
  5558.     case BEHIND_INDEXED:
  5559.       behind_indexed_pixels (s1, s, d, m, opacity,
  5560.                  affect, src1->w, src1->bytes,
  5561.                  src2->bytes, has_alpha1, has_alpha2);
  5562.       break;
  5563.         
  5564.     case REPLACE_INTEN:
  5565.       replace_inten_pixels (s1, s, d, m, opacity,
  5566.                 affect, src1->w, src1->bytes,
  5567.                 src2->bytes, has_alpha1, has_alpha2);
  5568.       break;
  5569.         
  5570.     case REPLACE_INDEXED:
  5571.       replace_indexed_pixels (s1, s, d, m, opacity,
  5572.                   affect, src1->w, src1->bytes,
  5573.                   src2->bytes, has_alpha1, has_alpha2);
  5574.       break;
  5575.         
  5576.     case ERASE_INTEN:
  5577.       erase_inten_pixels (s1, s, d, m, opacity,
  5578.                   affect, src1->w, src1->bytes);
  5579.       break;
  5580.         
  5581.     case ERASE_INDEXED:
  5582.       erase_indexed_pixels (s1, s, d, m, opacity,
  5583.                 affect, src1->w, src1->bytes);
  5584.       break;
  5585.         
  5586.     case ANTI_ERASE_INTEN:
  5587.       anti_erase_inten_pixels (s1, s, d, m, opacity,
  5588.                    affect, src1->w, src1->bytes);
  5589.       break;
  5590.         
  5591.     case ANTI_ERASE_INDEXED:
  5592.       anti_erase_indexed_pixels (s1, s, d, m, opacity,
  5593.                      affect, src1->w, src1->bytes);
  5594.       break;
  5595.         
  5596.     case NO_COMBINATION:
  5597.       g_warning("NO_COMBINATION");
  5598.       break;
  5599.         
  5600.     default:
  5601.       g_warning("UNKNOWN COMBINATION");
  5602.       break;
  5603.     }
  5604.     
  5605.     next_row:
  5606.       s1 += src1->rowstride;
  5607.       s2 += src2->rowstride;
  5608.       d += dest->rowstride;
  5609.       if (mask)
  5610.     m += mask->rowstride;
  5611.     }
  5612. }
  5613.  
  5614.  
  5615. void
  5616. combine_regions (PixelRegion     *src1,
  5617.          PixelRegion     *src2,
  5618.          PixelRegion        *dest,
  5619.          PixelRegion       *mask,
  5620.          unsigned char     *data,
  5621.          int          opacity,
  5622.          LayerModeEffects mode,
  5623.          int         *affect,
  5624.          int          type)
  5625. {
  5626.   int has_alpha1, has_alpha2;
  5627.   int i;
  5628.   struct combine_regions_struct st;
  5629.  
  5630.   /*  Determine which sources have alpha channels  */
  5631.   switch (type)
  5632.     {
  5633.     case COMBINE_INTEN_INTEN:
  5634.     case COMBINE_INDEXED_INDEXED:
  5635.       has_alpha1 = has_alpha2 = 0;
  5636.       break;
  5637.     case COMBINE_INTEN_A_INTEN:
  5638.       has_alpha1 = 1;
  5639.       has_alpha2 = 0;
  5640.       break;
  5641.     case COMBINE_INTEN_INTEN_A:
  5642.     case COMBINE_INDEXED_INDEXED_A:
  5643.       has_alpha1 = 0;
  5644.       has_alpha2 = 1;
  5645.       break;
  5646.     case COMBINE_INTEN_A_INTEN_A:
  5647.     case COMBINE_INDEXED_A_INDEXED_A:
  5648.       has_alpha1 = has_alpha2 = 1;
  5649.       break;
  5650.     default:
  5651.       has_alpha1 = has_alpha2 = 0;
  5652.     }
  5653.  
  5654.   st.opacity = opacity;
  5655.   st.mode = mode;
  5656.   st.affect = affect;
  5657.   st.type = type;
  5658.   st.data = data;
  5659.   st.has_alpha1 = has_alpha1;
  5660.   st.has_alpha2 = has_alpha2;
  5661.  
  5662.   /* cheap and easy when the row of src2 is completely opaque/transparent
  5663.      and the wind is otherwise blowing in the right direction.
  5664.   */
  5665.  
  5666.   /* First check - we can't do an opacity quickskip if the drawable
  5667.      has a mask, or non-full opacity, or the layer mode dictates
  5668.      that we might gain transparency.
  5669.   */
  5670.   st.opacity_quickskip_possible = ((!mask) && (opacity==255) &&
  5671.                    (!layer_modes[mode].decrease_opacity) &&
  5672.                    (layer_modes[mode].affect_alpha &&
  5673.                     has_alpha1 &&
  5674.                     affect[src1->bytes-1]) );
  5675.  
  5676.   /* Second check - if any single colour channel can't be affected,
  5677.      we can't use the opacity quickskip.
  5678.   */
  5679.   if (st.opacity_quickskip_possible)
  5680.     {
  5681.       for (i=0; i<src1->bytes-1; i++)
  5682.     {
  5683.       if (!affect[i])
  5684.         {
  5685.           st.opacity_quickskip_possible = FALSE;
  5686.           break;
  5687.         }
  5688.     }
  5689.     }
  5690.  
  5691.   /* transparency quickskip is only possible if the layer mode
  5692.      dictates that we cannot possibly gain opacity, or the 'overall'
  5693.      opacity of the layer is set to zero anyway.
  5694.    */
  5695.   st.transparency_quickskip_possible = ((!layer_modes[mode].increase_opacity)
  5696.                     || (opacity==0));
  5697.  
  5698.   /* Start the actual processing.
  5699.    */
  5700.   pixel_regions_process_parallel ((p_func)combine_sub_region, &st, 4,
  5701.                     src1, src2, dest, mask);
  5702. }
  5703.  
  5704. void
  5705. combine_regions_replace (PixelRegion   *src1,
  5706.              PixelRegion   *src2,
  5707.              PixelRegion   *dest,
  5708.              PixelRegion   *mask,
  5709.              unsigned char *data,
  5710.              int            opacity,
  5711.              int           *affect,
  5712.              int            type)
  5713. {
  5714.   int h;
  5715.   unsigned char * s1, * s2;
  5716.   unsigned char * d, * m;
  5717.   void * pr;
  5718.  
  5719.   for (pr = pixel_regions_register (4, src1, src2, dest, mask); pr != NULL; pr = pixel_regions_process (pr))
  5720.     {
  5721.       s1 = src1->data;
  5722.       s2 = src2->data;
  5723.       d = dest->data;
  5724.       m = mask->data;
  5725.  
  5726.       for (h = 0; h < src1->h; h++)
  5727.     {
  5728.  
  5729.       /*  Now, apply the paint mode  */
  5730.       apply_layer_mode_replace (s1, s2, d, m, src1->x, src1->y + h, opacity, src1->w,
  5731.                           src1->bytes, src2->bytes, affect);
  5732.  
  5733.       s1 += src1->rowstride;
  5734.       s2 += src2->rowstride;
  5735.       d += dest->rowstride;
  5736.       m += mask->rowstride;
  5737.     }
  5738.     }
  5739. }
  5740.  
  5741. /************************************/
  5742. /*       apply layer modes          */
  5743. /************************************/
  5744.  
  5745. int
  5746. apply_layer_mode (unsigned char   *src1,
  5747.           unsigned char   *src2,
  5748.           unsigned char  **dest,
  5749.           int              x,
  5750.           int              y,
  5751.           int              opacity,
  5752.           int              length,
  5753.           LayerModeEffects mode,
  5754.           int              bytes1,   /* bytes */
  5755.           int              bytes2,   /* bytes */
  5756.           int              has_alpha1,  /* has alpha */
  5757.           int              has_alpha2,  /* has alpha */
  5758.           int             *mode_affect)
  5759. {
  5760.   int combine;
  5761.  
  5762.   if (!has_alpha1 && !has_alpha2)
  5763.     combine = COMBINE_INTEN_INTEN;
  5764.   else if (!has_alpha1 && has_alpha2)
  5765.     combine = COMBINE_INTEN_INTEN_A;
  5766.   else if (has_alpha1 && !has_alpha2)
  5767.     combine = COMBINE_INTEN_A_INTEN;
  5768.   else
  5769.     combine = COMBINE_INTEN_A_INTEN_A;
  5770.  
  5771.   /*  assumes we're applying src2 TO src1  */
  5772.   switch (mode)
  5773.     {
  5774.     case NORMAL_MODE:
  5775.       *dest = src2;
  5776.       break;
  5777.  
  5778.     case DISSOLVE_MODE:
  5779.       /*  Since dissolve requires an alpha channels...  */
  5780.       if (! has_alpha2)
  5781.     add_alpha_pixels (src2, *dest, length, bytes2);
  5782.  
  5783.       dissolve_pixels (src2, *dest, x, y, opacity, length, bytes2,
  5784.                ((has_alpha2) ? bytes2 : bytes2 + 1), has_alpha2);
  5785.       combine = (has_alpha1) ? COMBINE_INTEN_A_INTEN_A : COMBINE_INTEN_INTEN_A;
  5786.       break;
  5787.  
  5788.     case MULTIPLY_MODE:
  5789.       multiply_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5790.       break;
  5791.  
  5792.     case DIVIDE_MODE:
  5793.       divide_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5794.       break;
  5795.  
  5796.     case SCREEN_MODE:
  5797.       screen_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5798.       break;
  5799.  
  5800.     case OVERLAY_MODE:
  5801.       overlay_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5802.       break;
  5803.  
  5804.     case DIFFERENCE_MODE:
  5805.       difference_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5806.       break;
  5807.  
  5808.     case ADDITION_MODE:
  5809.       add_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5810.       break;
  5811.  
  5812.     case SUBTRACT_MODE:
  5813.       subtract_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5814.       break;
  5815.  
  5816.     case DARKEN_ONLY_MODE:
  5817.       darken_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5818.       break;
  5819.  
  5820.     case LIGHTEN_ONLY_MODE:
  5821.       lighten_pixels (src1, src2, *dest, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5822.       break;
  5823.  
  5824.     case HUE_MODE: case SATURATION_MODE: case VALUE_MODE:
  5825.       /*  only works on RGB color images  */
  5826.       if (bytes1 > 2)
  5827.     hsv_only_pixels (src1, src2, *dest, mode, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5828.       else
  5829.     *dest = src2;
  5830.       break;
  5831.  
  5832.     case COLOR_MODE:
  5833.       /*  only works on RGB color images  */
  5834.       if (bytes1 > 2)
  5835.     color_only_pixels (src1, src2, *dest, mode, length, bytes1, bytes2, has_alpha1, has_alpha2);
  5836.       else
  5837.     *dest = src2;
  5838.       break;
  5839.  
  5840.     case BEHIND_MODE:
  5841.       *dest = src2;
  5842.       if (has_alpha1)
  5843.     combine = BEHIND_INTEN;
  5844.       else
  5845.     combine = NO_COMBINATION;
  5846.       break;
  5847.  
  5848.     case REPLACE_MODE:
  5849.       *dest = src2;
  5850.       combine = REPLACE_INTEN;
  5851.       break;
  5852.  
  5853.     case ERASE_MODE:
  5854.       *dest = src2;
  5855.       /*  If both sources have alpha channels, call erase function.
  5856.        *  Otherwise, just combine in the normal manner
  5857.        */
  5858.       combine = (has_alpha1 && has_alpha2) ? ERASE_INTEN : combine;
  5859.       break;
  5860.  
  5861.     case ANTI_ERASE_MODE:
  5862.       *dest = src2;
  5863.       combine = (has_alpha1 && has_alpha2) ? ANTI_ERASE_INTEN : combine;
  5864.       break;
  5865.  
  5866.     default :
  5867.       break;
  5868.     }
  5869.  
  5870.   /*  Determine whether the alpha channel of the destination can be affected
  5871.    *  by the specified mode--This keeps consistency with varying opacities
  5872.    */
  5873.   *mode_affect = layer_modes[mode].affect_alpha;
  5874.  
  5875.   return combine;
  5876. }
  5877.  
  5878.  
  5879. int
  5880. apply_indexed_layer_mode (unsigned char   *src1,
  5881.               unsigned char   *src2,
  5882.               unsigned char  **dest,
  5883.               LayerModeEffects mode,
  5884.               int              has_alpha1, /* has alpha */
  5885.               int              has_alpha2) /* has alpha */
  5886. {
  5887.   int combine;
  5888.  
  5889.   if (!has_alpha1 && !has_alpha2)
  5890.     combine = COMBINE_INDEXED_INDEXED;
  5891.   else if (!has_alpha1 && has_alpha2)
  5892.     combine = COMBINE_INDEXED_INDEXED_A;
  5893.   else if (has_alpha1 && has_alpha2)
  5894.     combine = COMBINE_INDEXED_A_INDEXED_A;
  5895.   else
  5896.     combine = NO_COMBINATION;
  5897.  
  5898.   /*  assumes we're applying src2 TO src1  */
  5899.   switch (mode)
  5900.     {
  5901.     case REPLACE_MODE:
  5902.       *dest = src2;
  5903.       combine = REPLACE_INDEXED;
  5904.       break;
  5905.  
  5906.     case BEHIND_MODE:
  5907.       *dest = src2;
  5908.       if (has_alpha1)
  5909.     combine = BEHIND_INDEXED;
  5910.       else
  5911.     combine = NO_COMBINATION;
  5912.       break;
  5913.  
  5914.     case ERASE_MODE:
  5915.       *dest = src2;
  5916.       /*  If both sources have alpha channels, call erase function.
  5917.        *  Otherwise, just combine in the normal manner
  5918.        */
  5919.       combine = (has_alpha1 && has_alpha2) ? ERASE_INDEXED : combine;
  5920.       break;
  5921.  
  5922.     default:
  5923.       break;
  5924.     }
  5925.  
  5926.   return combine;
  5927. }
  5928.  
  5929. static void
  5930. apply_layer_mode_replace (unsigned char  *src1,
  5931.               unsigned char  *src2,
  5932.               unsigned char  *dest,
  5933.               unsigned char  *mask,
  5934.               int             x,
  5935.               int             y,
  5936.               int             opacity,
  5937.               int             length,
  5938.               int             bytes1,   /* bytes */
  5939.               int             bytes2,   /* bytes */
  5940.               int            *affect)
  5941. {
  5942.   replace_pixels (src1, src2, dest, mask, length, opacity, affect, bytes1, bytes2);
  5943. }
  5944.